jpa-2.0 – 执行@PostLoad _after_热切地提取?

前端之家收集整理的这篇文章主要介绍了jpa-2.0 – 执行@PostLoad _after_热切地提取?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用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也许有可以控制这种行为?

解决方法

这可能太晚了,但是hibernate似乎不支持默认的jpa fetchtype选项
@OneToMany(orphanRemoval = false,fetch = FetchType.EAGER)

你必须使用hibernate特定的一个:

@LazyCollection(LazyCollectionOption.FALSE)

猜你在找的Java相关文章