Lazy Loadng error in JSON serializer

前端 未结 5 1931
鱼传尺愫
鱼传尺愫 2020-12-21 04:01

I have such kind of @OneToOne Hibernate relationShip

public class Address implements Serializable {

    private String id;
    private String city;
    priv         


        
相关标签:
5条回答
  • 2020-12-21 04:43

    The easiest solution: Don't serialize entities, use Value Objects.

    If that is not an option for you, make sure that the entity Object is detached.

    With JPA (2), you would use EntityManager.detach(entity), with plain Hibernate the equivalent is Session.evict(entity).

    0 讨论(0)
  • 2020-12-21 04:50

    Within your DAO method add Hibernate.initialize(<your getter method>); to resolve this.

    Student student = findById(<yourId>);
    Hibernate.initialize(student.getAddress());
    ...
    return student;
    

    Try like the above.

    0 讨论(0)
  • 2020-12-21 04:52

    There is another option that solves your problems. You can add this filter in web.xml

    <filter>
        <filter-name>springOpenEntityManagerInViewFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
        <init-param>
          <param-name>entityManagerFactoryBeanName</param-name>
          <param-value>entityManagerFactory</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>springOpenEntityManagerInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
    

    The problem is that entities are loaded lazy and serialization happens before they get loaded fully.

    0 讨论(0)
  • 2020-12-21 04:54

    Once I write a processor to handle this but now it's easy to fix this by using the jackson hibernate module.

    0 讨论(0)
  • 2020-12-21 04:54

    But how can I serialize to JSON lazy classes using standard jackson message converter which of cause I added to my XML file.

    First of all, I don't advise to use DTO/Value Object only to solve this issue.
    You may find it easy at the beginning but at each new development/change, the duplicate code means making twice modifications at each time... otherwise bugs.

    I don't mean that VO or DTO are bad smells but you should use them for reasons they are designed (such as providing a content/structure that differs according to logical layers or solving an unsolvable serialization problem).
    If you have a clean and efficient way to solve the serialization issue without VO/DTO and you don't need them, don't use them.

    And about it, there is many ways to solve lazy loading issue as you use Jackson with Hibernate entities.

    Actually, the simplest way is using FasterXML/jackson-datatype-hibernate

    Project to build Jackson module (jar) to support JSON serialization and deserialization of Hibernate (http://hibernate.org) specific datatypes and properties; especially lazy-loading aspects.

    It provides Hibernate3Module/Hibernate4Module/Hibernate5Module, extension modules that can be registered with ObjectMapper to provide a well-defined set of extensions related to Hibernate specificities.

    To do it working, you just need to add the required dependency and to add the Jackson Module available during processings where it is required.

    If you use Hibernate 3 :

      <dependency>
         <groupId>com.fasterxml.jackson.datatype</groupId>
         <artifactId>jackson-datatype-hibernate3</artifactId>
         <version>${jackson.version.datatype}</version>
      </dependency>
    

    If you use Hibernate 4 :

      <dependency>
         <groupId>com.fasterxml.jackson.datatype</groupId>
         <artifactId>jackson-datatype-hibernate4</artifactId>
         <version>${jackson.version.datatype}</version>
      </dependency>
    

    And so for...

    Where jackson.version.datatype should be the same for the used Jackson version and the ackson-datatype extension.

    If you use or may use Spring Boot, you just need to declare the module as a bean in a specific Configuration class or in the SpringBootApplication class and it will be automatically registered for any Jackson ObjectMapper created.

    The 74.3 Customize the Jackson ObjectMapper Spring Boot section states that :

    Any beans of type com.fasterxml.jackson.databind.Module will be automatically registered with the auto-configured Jackson2ObjectMapperBuilder and applied to any ObjectMapper instances that it creates. This provides a global mechanism for contributing custom modules when you add new features to your application.

    For example :

    @Configuration
    public class MyJacksonConfig {
    
        @Bean
        public Module hibernate5Module() {
          return new Hibernate5Module();
        }
    }
    

    or :

    @SpringBootApplication
    public class AppConfig {
    
        public static void main(String[] args) throws IOException {
          SpringApplication.run(AppConfig.class, args);
        }
    
        @Bean
        public Module hibernate5Module() {
          return new Hibernate5Module();
        }
    }
    
    0 讨论(0)
提交回复
热议问题