使用标准 JPA 注释时,您可以指定FetchType.LAZY
非集合字段(即@ManyToOne
和@OneToOne
)。在这种情况下,Hibernate 似乎在内部使用“代理”获取。但是代理获取在继承方面存在问题,我认为将无代理获取与字节码检测结合使用会更好。不幸的是,Hibernate 仍然要求您在 -file 中指定“no-proxy”hbm
或使用特定于 Hibernate 的@LazyToOne
注释。
我的问题是:Hibernate 是否支持对所有非收集字段使用无代理获取策略的配置选项,即FetchType.LAZY
?
这是我需要的:一方面,在大多数情况下,我只想使用 JPA 注释。另一方面,我想避免继承和惰性字段的问题。而且我不喜欢将所有内容都包装在接口中的想法,因为我在当前项目中使用 DDD,所以我认为我的域模型中不应该存在样板垃圾,只有纯业务逻辑。
我有一个糟糕的解决方法的想法:通过使用字节码修改,我在出现的@LazyToOne
任何地方添加注释@ManyToOne
。但如果存在,我更喜欢内置的 Hibernate 功能。
这是代理获取的(众所周知的)问题,以使事情更清楚:
@Entity @DiscriminatorColumn("t") @DiscriminatorValue("")
public abstract class A {
@Id private Integer id;
}
@Entity @DiscriminatorValue("B")
public abstract class B extends A {
}
@Entity @DiscriminatorValue("C")
public abstract class C extends A {
}
@Entity public class D {
@Id private Integer id;
@ManyToOne(fetch = FetchType.LAZY) private A a;
public A getA() {
return a;
}
}
准备:
D d = new D();
C c = new C();
d.setA(c);
em.persist(d);
并且断言失败(在另一个 EM,另一个事务中):
D d = em.createQuery("select d from D d", D.class).getSingleResult();
List<C> cs = em.createQuery("select c from C c", C.class).getResultList();
assert d.getA() instanceof C;
assert d.getA() == cs.get(0);
这是我要解决上述断言的方法:
@Entity public class D {
@Id private Integer id;
@ManyToOne(fetch = FetchType.LAZY) @LazyToOne(LazyToOneOption.NO_PROXY)
private A a;
public A getA() {
return a;
}
}
而且我不希望在没有@LazyToOne
注释的情况下默认启用相同的功能。