Avoid Jackson serialization on non fetched lazy objects

前端 未结 14 2067
终归单人心
终归单人心 2020-11-22 13:02

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

14条回答
  •  北恋
    北恋 (楼主)
    2020-11-22 13:36

    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.

    • The module was added to both the JSON and XML processors

    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 {
    

提交回复
热议问题