I have a simple controller that return a User object, this user have a attribute coordinates that have the hibernate property FetchType.LAZY.
When I try to get this
The following solution is for Spring 4.3, (non-boot) & Hibernate 5.1 where we transitioned all fetchtypes to fetch=FetchType.LAZY from cases of fetch=FetchType.EAGER for performance reasons. Immediately we saw the com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy exception due to the lazy load issue.
First, we add the following maven dependency:
com.fasterxml.jackson.datatype
jackson-datatype-hibernate5
Then the following is added to our Java MVC configuration file:
@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void extendMessageConverters(List> converters) {
Hibernate5Module h5module = new Hibernate5Module();
h5module.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
h5module.enable(Hibernate5Module.Feature.FORCE_LAZY_LOADING);
for (HttpMessageConverter> mc : converters){
if (mc instanceof MappingJackson2HttpMessageConverter || mc instanceof MappingJackson2XmlHttpMessageConverter) {
((AbstractJackson2HttpMessageConverter) mc).getObjectMapper().registerModule(h5module);
}
}
return;
}
Notes:
You need to create and configure the Hibernate5Module to get behavior similar to Jackson without this module. The default makes incompatible assumptions.
Our WebMvcConfigurerAdapter has a lot of other configuration in it and we wanted to avoid another configuration class, which is why we didn't use the WebMvcConfigurationSupport#addDefaultHttpMessageConverters function that has been referred to on other posts.
WebMvcConfigurerAdapter#configureMessageConverters disables all of Spring's internal configuration of message converters. We preferred to avoid the potential issues around this.
Using extendMessageConverters enabled access to all the automatically-configured Jackson classes without losing the configuration of all other message converters.
Using getObjectMapper#registerModule we were able to add the Hibernate5Module to the existing converters.
This addition solved the issue with Hibernate and lazy loading but caused a residual issue with the generated JSON format. As reported in this github issue, the hibernate-jackson lazy load module currently ignores the @JsonUnwrapped annotation, leading to potential data errors. This happens regardless of the force-loading feature setting. The problem has been there since 2016.
Note
It appears that by adding the following to classes that are lazy-loaded, the built-in ObjectMapper works without adding the hibernate5 module:
@JsonIgnoreProperties( {"handler","hibernateLazyInitializer"} )
public class Anyclass {