Hibernate LAZY获取未初始化实例



两天前我遇到了一个懒惰关联的问题,至今仍未找到对这种行为的解释。这是我简化的类层次结构:

@Entity
@Table(name="A")
public class A
{
    @Id
    @GeneratedValue
    @Column(name="ID")
    private int id;
    @OneToMany(mappedBy="a", fetch=FetchType.LAZY, cascade=CascadeType.ALL) 
    private Set<B> listB = new HashSet<B>();
}
@Entity
@Table(name="B")
public class B
{
    @Id
    @GeneratedValue
    @Column(name="ID")
    private int id;
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="A_ID")
    private A a;
    @ManyToOne(fetch=FetchType.LAZY)      // ERROR!
    // @ManyToOne(fetch=FetchType.EAGER)  // OK
    @JoinColumn(name="C_ID")
    private C c;
}
@Entity
@Table(name="C")
public class C {
    @Id
    @GeneratedValue
    @Column(name="ID")
    private int id; 
}

当我试图从数据库中读取简单的结构:A->B->C时,我得到了以下结果:

System.out.println(a.getId());                  // 1
for (B b : a.getListB()) {                      
    System.out.println(b.getId());              // 1
    C c = b.getC();
    System.out.println(c.getId());              // 0 !!!
}

正如您所看到的,C的实例并没有正确初始化。在将B类中字段c的获取类型从LAZY更改为EAGER之后,一切都正常!

我怀疑有一些CGLIB魔术,但在规范和谷歌中都找不到线索。有人能解释一下吗?

谢谢你的帮助!!!

如果您想了解延迟加载,请参阅以下答案;它很好地定义了它。

已修复。我的问题不对。很抱歉实体类的getter和setter有最后一个修饰符。它打破了单一价值的关联,就像多对一一样。假设我错过了hibernate日志中的一些警告。。。我认为在这种情况下,通过hibernate抛出一个异常会更好。

最新更新