【问题标题】:Hibernate5Module doesn't fetch OneToMany collectionHibernate5Module 不获取 OneToMany 集合
【发布时间】:2020-07-25 09:40:58
【问题描述】:

首先,我有两个相关实体映射为双向 OneToMany:

    @Data
    @Entity
    @Table(name = "tbl_parent")
    public class Parent {

    @Id
    @Column(name = "parent_id")
    private Long id;

    ...

    @OneToMany(mappedBy = "parent")
        private List<Child> children = new ArrayList<>();
}

@Data
@Entity
@Table(name = "tbl_child")
@ToString(exclude = "parent")
public class Child {

    @Id
    @Column(name = "child_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private Parent parent;
}

但是,在序列化过程中发生无限循环时,我为父实体的 findAll() 方法使用 StackOverFlow。

然后我在 application.yml 中添加了属性:

spring:jsp:open-in-view: false

还有另一个序列化问题。为了解决它,我在 build.gradle 中添加了依赖项:

implementation "com.fasterxml.jackson.datatype:jackson-datatype-hibernate5"

及配置类:

@Configuration
public class JacksonConfiguration {

    @Bean
    public JavaTimeModule javaTimeModule() {
        return new JavaTimeModule();
    }

    @Bean
    public Jdk8Module jdk8TimeModule() {
        return new Jdk8Module();
    }

    @Bean
    public Hibernate5Module hibernate5Module() {
        return new Hibernate5Module();
    }

}

现在我没有错误,但父实体中的列表始终为空。

我做错了什么?如何在没有 StackOverflow 的情况下获取所有相关的子实体?

【问题讨论】:

  • 你能显示你在数据库中的数据吗?你是如何查询他们的
  • 我不确定为什么在这种情况下需要数据。我创建了接口ParentRepository extends JpaRepository,只是普通情况
  • 现在 sql 语句看起来像 select * from parent。正如我所说,它只是不获取相关的子实体。仅从父表中选择一项。
  • 那么如果你从父表中选择,那你为什么期望子表出现呢?
  • 当您在获取数据时遇到问题,您认为不需要数据?

标签: spring hibernate spring-data-jpa lombok


【解决方案1】:

如果两个类都有 @Data 和 collections/toStrings 相互提及,来自 Lombok 的 @Data 注释可能会由于类之间的循环依赖关系而导致堆栈溢出。

Lombok.hashCode issue with "java.lang.StackOverflowError: null"

【讨论】:

    【解决方案2】:

    问题很简单:您不能希望序列化双向关联的双方。如果您尝试这样做,您将获得带有children 属性的Parent 的JSON 表示,并且children 中的每个对象都将有一个parent 属性,每个parent 都包含一个children属性等等,令人作呕

    根据您的描述,我假设您想选择不序列化 parent 属性,在这种情况下,您应该将 @JsonIgnore 放在 Child.parent 上。

    此外,由于您启用了HibernateModule,默认情况下会忽略惰性属性,您应该禁用它,启用它的FORCE_LAZY_LOADING 功能,或者配置Parent.children 以急切获取。第三个选项也消除了对@JsonIgnore 的需要。

    (所有三个选项都可能产生深远的影响,因此您需要决定哪一个最适合您的用例;还请注意,必须使用 open-jpa-in-view 是一种代码异味,因为强制延迟加载发生在任何事务上下文)

    【讨论】:

      猜你喜欢
      • 2015-09-08
      • 2018-05-13
      • 2012-01-05
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多