Reputation: 3064
Is there a way to disable enhancement for play framework model classes?
The reason why I'm asking this is because I want to serialize the model objects to JSON but as soon as json serializer touches any non initialized model,
that model will be initialized causing an extra database hit and the resulting json will be bloated with unnecessary model objects. I tried excluding the models.*
from the application.conf and using a ServerConfigStartup
with this call serverConfig.addClass(Model.class)
or that call serverConfig.addPackage("models")
but neither of them worked for me.
Upvotes: 0
Views: 425
Reputation: 3064
I found a way around the loading of models that are not needed during the json serialization. First I had to modify the way Jackson serializes the model objects by using this:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.PUBLIC_ONLY);
This forces Jackson to use the field directly but your model fields have to be public. This is still not enough because uninitialized model sets will still be loaded during the serialization. To get around this, I had to null the sets before the serialization process by using reflection as follows:
for (Field field : model.getClass().getFields())
{
Object fieldObject = field.get(model);
if (fieldObject instanceof BeanSet)
{
BeanSet beanSet = (BeanSet) fieldObject;
//checks if the set is loaded or not
if (beanSet.isReference())
{
field.set(model, null);
}
}
}
Now your model is safe to pass to the Jackson serializer without uninitialized model objects loaded during the serialization.
String jsonString = objectMapper.writeValueAsString(model);
JsonNode jsonNode = Json.parse(jsonString);
Using @JsonIgnore
will also work but it is not reliable in the long run as James mentioned because you may have a need for the model object that you are ignoring later.
Upvotes: 0
Reputation: 12850
Ebean requires that model classes be enhanced. You can't use a model class with ebean if it's not enhanced.
So, your options are, don't use ebean, or don't serialise your model objects to JSON. The latter is considered best practice, tying your REST API data objects to your database models is not a good idea, for the reason of the problem that you are experiencing now - the two models usually are conceptually different - the database model has references to other models, while the JSON model doesn't. So use different classes to represent the different models.
There is another option, use Jackson annotations like @JsonIgnore to ignore these properties. But really, that's a slippery slope, as your codebase evolves it becomes next to impossible to reason about what your JSON will look like as you start to use more of these annotations on your classes, and maintaining the models, ensuring you don't break your public REST API, becomes a nightmare.
Upvotes: 1