I need to store some entities in database with custom (dynamic created) columns. For reach that goal I created additional column in tables with dynamic columns and type of column is JSONB (I work with postgresql on this project). On application side I'm storing these additional columns in Map using hibernate types library from Vlad Mihalcea. To return required by web resources from my application I need map table onto java's pojo and after that just send it. But I faced with problem when converting my pojo to json. Web requires a simple JSON without nested propetries, for example:
{
"name": "name",
"1": 100,
"2": true
}
On the JSON above 1 and 2 are custom columns (yeah, we decided to use ids for that goal). But, if I'm mapping my class with Map as class property, response will contain nested structure:
{
"name": "name",
"customAttributes": {
"1": 100,
"2": "test"
}
}
Actually, it's not a big deal to cast class into the Map, remove key "customAttributes" and put value of this map back. My solution is in code below:
public Map<String, Object> mapToResource(Account account) {
var accountMap = objectMapper.convertValue(account, new TypeReference<Map<String, Object>>() {});
if (isClassHasCustomAttributes(account.getClass())) {
var customAttributesMap = account.getCustomAttributes();
accountMap.remove("customAttributes");
accountMap.putAll(customAttributesMap);
}
return accountMap;
}
private boolean isClassHasCustomAttributes(Class<?> classUnderCheck) {
return Arrays.stream(classUnderCheck.getDeclaredFields()).anyMatch(field -> field.getName().equals("customAttributes"));
}
I added check for property named customAttributes because not all entities contain Map as property and I'm using generics for all my tables in app. I'm not sure that casting all my classes into Map on controller layer is a good solution for this sutiation. In summary, I need to know - is there a better way to return requested entity without casting classes into Map<String, Object> or no?