使用JPA2 / Hibernate,我创建了一个实体A,它具有到实体X的单向映射(见下文).在A里面,我也有一个暂时的成员“t”,我试图用@PostLoad方法计算.计算需要访问有争议的X:
@Entity public class A { // ... @Transient int t; @OnetoMany(orphanRemoval = false,fetch = FetchType.EAGER) private List listofX; @PostLoad public void calculateT() { t = 0; for (X x : listofX) t = t + x.someMethod(); } }
但是,当我尝试加载这个实体时,我得到一个“org.hibernate.LazyInitializationException:非法访问加载集合”错误.
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:363) at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108) at org.hibernate.collection.PersistentBag.get(PersistentBag.java:445) at java.util.Collections$UnmodifiableList.get(Collections.java:1154) at mypackage.A.calculateT(A.java:32)
在调试时看hibernate的代码(AbstractPersistentCollection.java),我发现:
1)我的@PostLoad方法在“listofX”成员初始化之前调用
2)Hibernate的代码有一个明确的检查,以防止在@PostLoad期间初始化一个热切取得的集合:
protected final void initialize(boolean writing) { if (!initialized) { if (initializing) { throw new LazyInitializationException("illegal access to loading collection"); } throwLazyInitializationExceptionIfNotConnected(); session.initializeCollection(this,writing); } }
我想要解决的唯一方法是停止使用@PostLoad并将初始化代码移动到getT()访问器中,添加一个同步块.但是,我想避免这种情况.
那么,是否有一种方法可以在@PostLoad被调用之前执行抢购?我不知道JPA的设施是这样做的,所以我希望有一些我不知道的东西.
此外,Hibernate的专有API也许有可以控制这种行为?
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。