急切地获取后执行@PostLoad?
使用 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 可以控制这种行为?
Using JPA2/Hibernate, I've created an entity A that has a uni-directional mapping to an entity X (see below). Inside A, I also have a transient member "t" that I am trying to calculate using a @PostLoad method. The calculation requires access to the assosiated Xs:
@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();
}
}
However, when I try to load this entity, I get a "org.hibernate.LazyInitializationException: illegal access to loading collection" error.
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)
Looking at hibernate's code (AbstractPersistentCollection.java) while debugging, I found that:
1) My @PostLoad method is called BEFORE the "listOfX" member is initialized
2) Hibernate's code has an explicit check to prevent initialization of an eagerly fetched collection during a @PostLoad:
protected final void initialize(boolean writing) {
if (!initialized) {
if (initializing) {
throw new LazyInitializationException("illegal access to loading collection");
}
throwLazyInitializationExceptionIfNotConnected();
session.initializeCollection(this, writing);
}
}
The only way I'm thinking to fix this is to stop using @PostLoad and move the initialization code into the getT() accessor, adding a synchronized block. However, I want to avoid that.
So, is there a way to have eager fetching executed prior to @PostLoad being called? I don't know of a JPA facility to do that, so I'm hoping there's something I don't know.
Also, perhaps Hibernate's proprietary API has something to control this behaviour?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这可能为时已晚,但 hibernate 似乎不支持默认的 jpa fetchtype 选项
您必须使用 hibernate 特定的选项:
This might be too late, but hibernate seems not to support the default jpa fetchtype option
You must use the hibernate specific one:
我不知道如何解决这个问题,但我认为一点重构可能会有所帮助,想法是将代码移动到
@PostConstruct
所以例如你的类将是:
}
服务器将调用一旦完成对 bean 的所有容器服务的初始化,就立即进行 PostConstruct。
I don't know how to fix this but I think a little refactoring might help, the idea would be to move the code to a
@PostConstruct
so for example your class would be:
}
The server will call PostConstruct as soon as it has completed initializing all the container services for the bean.
更新了错误报告的链接:
https://hibernate.atlassian.net/browse/HHH-6043< /a>
这在 4.1.8 和 4.3.0 或更高版本中已修复
Updated link to bug report:
https://hibernate.atlassian.net/browse/HHH-6043
This is fixed in 4.1.8 and 4.3.0 or later