modelplayframework-2.0ebean

Serializer generate a NullPointerException due to a Lazy join in EBean


I have a serializer for a Model, like this:

@Override
public void serialize(MyModel model, JsonGenerator generator, SerializerProvider serializer) throws IOException,JsonProcessingException {
    if (model == null) return;
    
    SimpleDateFormat en = new SimpleDateFormat("yyyy-MM-dd");
    
    generator.writeStartObject();
    
    generator.writeNumberField("id", model.id);
    generator.writeStringField("name", model.name);
    generator.writeStringField("display", model.toString());
    
    SubModel subModel = model.subModel;

    // HERE IT IS :
    subModel.refresh(); // required to not have a nullpointerexception
    // If I don't do that, the subModel.xxxx will throw a NullPointerException
    // If I log the content :
    Logger.info(String.valueOf(subModel));

    // It will work (display the toString()) AND the following won't throw a NullPointerException

    generator.writeObjectFieldStart("quotas");
        generator.writeNumberField("id", subModel.id);
        generator.writeStringField("display", subModel.toString());
    generator.writeEndObject();


    generator.writeEndObject();
    generator.close();
}

Why? Is there a way to avoid having to call a refresh() or something else?

By the way, is it possible to use a serializer inside a serializer : In my case, I'd like to list all the properties of model, but I'd like to list just a part of subModel. That the aims of this Serializer.

But as far as I know, I add to list all the properties and add them to the generator (line 9 -> 11). Is it possible to serialize all direct properties of a model with adding the submodel (ManyToOne relations), without using the @JsonIgnore on the relation?


Solution

  • AFAIK, sometimes, Ebean has some difficulties to make joins with public properties, so try by using a getter in your model: getSubmodel():

    public class MyModel extends Model {
    
       ...
    
       private SubModel subModel;
    
       public SubModel getSubModel() {
          return this.subModel;
       }
    }