Hibernate无法获取多对多关联数据问题求助
问题解决方案
一、TableA的tableBs集合为空的解决办法
1. 检查数据库字段与实体映射的大小写匹配
PostgreSQL默认会将未加引号的标识符转为小写,若你创建中间表TableAB时用的是小写字段名(比如tableaid、tablebid),而实体中@JoinColumn指定的是TableAId、TableBId,会导致Hibernate无法正确关联字段。
解决:
- 修改实体中的
@JoinColumn名称为数据库实际的小写字段:
@JoinTable(name = "TableAB", joinColumns = {@JoinColumn(name="tableaid")}, inverseJoinColumns = {@JoinColumn(name="tablebid")})
- 或开启Hibernate全局引号配置,保留标识符大小写:在配置文件中添加
hibernate.globally_quoted_identifiers=true
2. 修复Lombok全参构造函数的影响
@AllArgsConstructor生成的全参构造函数,会在Hibernate实例化TableA时,若传入的tableBs为null,覆盖类中默认初始化的new HashSet<>(),导致集合为空。
解决:
- 移除
@AllArgsConstructor,改用@RequiredArgsConstructor(仅包含非空字段); - 或给
tableBs字段添加@Builder.Default注解,确保Lombok生成的构造/建造器不会覆盖初始值:
@Builder.Default private Set<TableB> tableBs = new HashSet<>();
3. 在查询中添加DISTINCT去重
JOIN FETCH会返回重复的TableA实例(每个关联的TableB对应一条记录),Hibernate若不进行去重,可能无法正确合并关联集合。修改查询语句:
session.createQuery("SELECT DISTINCT a FROM TableA a JOIN FETCH a.tableBs", TableA.class).list()
二、懒加载关联被意外触发的解决办法
TableB与TableC等懒加载关联被触发查询,大概率是Lombok的@Data注解生成的toString()、equals()、hashCode()方法导致——这些方法会访问关联集合,触发Hibernate懒加载初始化。
解决:
- 用
@Getter、@Setter代替@Data,手动控制生成的方法; - 或保留
@Data,但排除关联集合的toString/equals/hashCode生成:
@Data @AllArgsConstructor @NoArgsConstructor @Entity @Table(name = "TableA") @ToString(exclude = "tableBs") @EqualsAndHashCode(exclude = "tableBs") class TableA { // ... 字段省略 }
@Data @AllArgsConstructor @NoArgsConstructor @Entity @Table(name = "TableB") @ToString(exclude = {"tableAs", "tableCs"}) @EqualsAndHashCode(exclude = {"tableAs", "tableCs"}) class TableB { // ... 字段省略 }
内容的提问来源于stack exchange,提问作者Klunk
相关产品推荐
相关产品推荐

