gpt4 book ai didi

jpa-2.0 - 急切地获取后执行@PostLoad?

转载 作者:行者123 更新时间:2023-12-02 09:01:27 25 4
gpt4 key购买 nike

使用 JPA2/Hibernate,我创建了一个实体 A,它具有到实体 X 的单向映射(见下文)。在 A 内部,我还有一个 transient 成员“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的代码(AbstractPercientCollection.java),我发现:

1) 在初始化“listOfX”成员之前调用我的 @PostLoad 方法
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() 访问器中,添加同步块(synchronized block)。但是,我想避免这种情况。

那么,有没有办法在调用 @PostLoad 之前执行急切的获取?我不知道 JPA 设施可以做到这一点,所以我希望有一些我不知道的事情。

另外,也许 Hibernate 的专有 API 可以控制这种行为?

最佳答案

这可能为时已晚,但 hibernate 似乎不支持默认的 jpa fetchtype 选项

@OneToMany(orphanRemoval = false, fetch = FetchType.EAGER)

您必须使用 hibernate 特定的:

@LazyCollection(LazyCollectionOption.FALSE)

关于jpa-2.0 - 急切地获取后执行@PostLoad?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4498262/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com