不存在具有给定标识符的行:将 ManyToMany 关系从懒惰更改为急切时的奇怪行为

No row with the given identifier exists: Strange behavior when changing a ManyToMany relationship from lazy to eager

我在尝试加载实体时遇到了一个奇怪的行为,并且出现了以下异常

  org.springframework.orm.hibernate4.HibernateObjectRetrievalFailureException: 
    No row with the given identifier exists: [com.xxx.entity.Role#4545]

我的 hibernate 实体看起来很复杂,我希望我能让它尽可能简单:

@Entity
class Employee {   
   @ManyToMany
   private List<BB> bbList = new ArrayList<>();
}

@Entity
class BB extends CC{

}

@Entity
@Inheritance(strategy = JOINED)
abstract class CC {
   @ManyToOne(optional = false)
   @JoinColumn(name = "ID_XXX_DIM", nullable = false)
   private Dimension dimension;
}

@Entity
class Dimension {
  @ManyToMany(fetch = FetchType.EAGER)
  private List<Role> roles = new ArrayList<Role>();
}

我想做的是使用休眠条件列出 Employee 个对象。 但只有当我改变

时它才有效
@ManyToMany(fetch = FetchType.EAGER)
private List<Role> roles = new ArrayList<Role>();

@ManyToMany(fetch = FetchType.LAZY)
private List<Role> roles = new ArrayList<Role>();

你能告诉我为什么我在使用 eager 时会出现异常 属性

    org.springframework.orm.hibernate4.HibernateObjectRetrievalFailureException: 
No row with the given identifier exists: [com.xxx.entity.Role#4545]

此异常的根本原因是 Hibernate Criteria 中的一个错误,该错误会生成错误的 SQL 查询,其中不同的主键具有相同的别名。 这是生成的查询的快照,您可以看到别名 ID2_8_ 对于不同的表列是重复的。

select composite1_.ID_RSK_IND as ID2_8_, dimension8_.MNE_DIM as MNE3_90_4_, 
roles9_.ID_GRP_DIM as ID1_90_8_, role10_.ID_ROL as ID2_8_

Oracle 可以处理这种情况,但 hibernate 会尝试使用另一个实体的键加载该实体。

作为解决方法,我发现添加 @Fetch(value = FetchMode.SUBSELECT) 将解决这个错误,我不知道为什么但它有效。

@ManyToMany(fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
private List<Role> roles = new ArrayList<Role>();