Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jackson - do not serialize lazy objects

I have an entity:

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column
    private String title;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
    private List<Genre> genre;

}

Then I have a controller whose purpose is to retrieve books, my problem is that, the genre field is being included in the json response of my controller. Any way I can exclude those fields that are lazy loaded when jackson serializes the object?

This is the configuration of my ObjectMapper:

Hibernate4Module hm = new Hibernate4Module();
hm.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false);
registerModule(hm);
configure(SerializationFeature.INDENT_OUTPUT, true);

Thanks!

I can't mark it as JsonIgnore, as it will be forever out of the serialization box. There will be times where I will need to retrieve the genres along with the book, and by then I will use "fetch join" on my query so it will not be null.

like image 578
lorraine Avatar asked Sep 18 '14 07:09

lorraine


People also ask

Does Jackson require serializable?

Jackson actually doesn't need classes to implement Serializable but I'm going to add it anyway. Writing about a serialization framework and not implementing Serializable might seem strange.

Does Jackson serialize null fields?

With its default settings, Jackson serializes null-valued public fields. In other words, resulting JSON will include null fields. Here, the name field which is null is in the resulting JSON string.

Does Jackson serialize getters?

Jackson by default uses the getters for serializing and setters for deserializing.

What does Jackson ObjectMapper do?

The Jackson ObjectMapper can parse JSON from a string, stream or file, and create a Java object or object graph representing the parsed JSON. Parsing JSON into Java objects is also referred to as to deserialize Java objects from JSON. The Jackson ObjectMapper can also create JSON from Java objects.


2 Answers

You can do this with the Jackson @JsonInclude annotation.

According to the latest version's javadoc (2.4 right now) you can specify with a simple annotation if to include or not the annotated property if the field value is null or empty.

By default, it's JsonInclude.Include.ALWAYS, and this means that even if your lazily not-loaded values are null, Jackson does include the property.

Specifying to don't include empty or null values can significantly reduce the size of the JSON response, with all the benefits included..

If you want to change this behavior, you can add the annotation at class-level or single property/getterMethod level.

Try to add the following annotations to the fields you don't want to include if empty:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
private List<Genre> genre;
like image 184
Davide Rossi Avatar answered Sep 29 '22 11:09

Davide Rossi


You can use a spring configuration to disable force lazy loading by default!

@Configuration
public class JacksonConfig {
    
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        Hibernate5Module hibernate5Module = new Hibernate5Module();
        hibernate5Module.configure(Feature.FORCE_LAZY_LOADING, false);
        // Enable below line to switch lazy loaded json from null to a blank object!
        //hibernate5Module.configure(Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true);
        mapper.registerModule(hibernate5Module);
        return mapper;
    }
}
like image 43
zbishop Avatar answered Sep 29 '22 10:09

zbishop