配置了 Hibernate 5 模块的 Jackson Serialize 上的延迟初始化异常

问题描述 投票:0回答:1

当子元素(即孙子集合)的成员集合延迟初始化时,我在 Jackson FasterXML 序列化为 JSON 时遇到问题。

以下是实体外观的示例:

@Entity 
public class Parent {
 
    @ManyToMany(fetch = FetchType.LAZY)
    @JsonManagedReference 
    private List<Child> children; 

}
   @Entity 
   public class Child {

        @ManyToMany(fetch = FectchType.LAZY)
        @JsonBackReference
        private List<Parent> parent;
     
        @OneToMany(fetch = FectchType.LAZY) 
        @JsonManagedReference
        private List<Grandchild> grandChildren; 

   }

应用程序比较大,实体较多,实体之间关系较多。如果我急切地加载所有内容或使用属性

spring.jpa.open-in-view=true
,那将会非常慢。相反,所需实体的子级会在数据库事务中加载,而其他所有内容都是延迟初始化的。

序列化时抛出的异常如下:

com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: domain.Child.grandchildren, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->domain.Parent["children"]->org.hibernate.collection.internal.PersistentBag[0]->domain.Child["grandChildren"])

当然,考虑到这一点,杰克逊需要序列化那些延迟初始化的属性和它发现为空的成员集合 - 但我还没有弄清楚如何做到这一点。

我做了研究,发现有一个模块可以帮助解决这个问题:

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-hibernate5</artifactId>
    </dependency>

所以我按如下方式配置了 Jackson - 但例外仍然存在。

@Configuration
public class JacksonConfig {


    @Bean
    public MappingJackson2HttpMessageConverter configureObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        Hibernate5Module hibernate5Module = new Hibernate5Module();

        hibernate5Module.configure(Hibernate5Module.Feature.FORCE_LAZY_LOADING, false);
        hibernate5Module.configure(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION, false);
        hibernate5Module.configure(Hibernate5Module.Feature.REQUIRE_EXPLICIT_LAZY_LOADING_MARKER, false);
        hibernate5Module.configure(Hibernate5Module.Feature.WRITE_MISSING_ENTITIES_AS_NULL, true);
        objectMapper.registerModule(hibernate5Module);

        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(objectMapper);
        return converter;
    }
}

我被困住了!我不知道为什么我提供的配置不起作用。

依赖信息:

  • 春季启动
    2.6.6
  • 休眠
    5.6.7.Final
  • 杰克逊
    2.13.2
  • Jackson 数据类型 Hibernate5
    2.13.2
java json spring hibernate jackson
1个回答
0
投票

忽略惰性获取字段的自定义过滤器

自定义过滤器

import jakarta.persistence.Persistence;
 
public class LazyFieldsFilter {

    @Override
    public boolean equals(Object obj) {
        return !Persistence.getPersistenceUtil().isLoaded(obj);
    }

}

使用过滤器

@Entity
@Table(name = CUSTOMER_DB_TABLES.CUSTOMER_ORDER_PRODUCTS)
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderProduct {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = LazyFieldsFilter.class)
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "product_method_id")
    private ShippingMethod shippingMethod;

}

信用:JavaChina

© www.soinside.com 2019 - 2024. All rights reserved.