Jpa-2.0 – execute @ postload_ after_ Eagerly extract?
Using JPA2 / Hibernate, I created an entity a with a one-way mapping to entity x (see below) In a, I also have a temporary member "t". I try to calculate it with @ postload method Computing requires access to disputed 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();
}
}
However, when I try to load this entity, I get an "org. Hibernate. Lazyinitializationexception: illegal access to the loaded 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 the hibernate code (abstractpersistentcollection. Java) during debugging, I found that:
1) my @PostLoad method has a clear check on the code that calls the 2] Hibernate before the "listOfX" member initializes, so as to prevent initialization of a hot collection within @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 want to solve this problem is to stop using @ postload, move the initialization code to the gett () accessor, and add a synchronization block But I want to avoid this
So, is there a method to perform snapping up before @ postload is called? I don't know what JPA facilities do, so I hope there are some things I don't know
In addition, perhaps hibernate's proprietary API can control this behavior?
Solution
This may be too late, but hibernate does not seem to support the default JPA fetchtype option
@OneToMany(orphanRemoval = false,fetch = FetchType.EAGER)
You must use a specific one of Hibernate:
@LazyCollection(LazyCollectionOption.FALSE)
