Execute @PostLoad _after_ eagerly fetching?

Related searches

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?

This might be too late, but hibernate seems not to support the default jpa fetchtype option

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

You must use the hibernate specific one:

@LazyCollection(LazyCollectionOption.FALSE)

jpa 2.0 - Execute @PostLoad _after_ eagerly fetching? -, using jpa2/hibernate, i've created entity has uni-directional mapping entity x (see below). inside a, have transient member "t" trying calculate using @postload� 11 Execute @PostLoad _after_ eagerly fetching? Dec 21 '10. 6 Merging huge sets (HashSet) in Scala Aug 3 '11. 6 JAXB: Empty string does not produce empty element Jul 6

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:

@Entity  
public class A {  
    // ...
    @Transient
    int t;

@OneToMany(orphanRemoval = false, fetch = FetchType.EAGER)  
private List listOfX;  

@PostConstruct
public void calculateT() {
    t = 0;
    for (X x : listOfX)
        t = t + x.someMethod();
}

}

The server will call PostConstruct as soon as it has completed initializing all the container services for the bean.

[HHH-12279] LOAD event is triggered before EAGER associations , In my @PostLoad callback, I access those eagerly fetched associations (which Once all of the container entities have executed their @PostLoad callback, The PostLoad method for an entity is invoked after the entity has been loaded into� Stack Exchange network consists of 177 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

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

The best way to lazy load entity attributes using JPA and Hibernate , When fetching an entity, all attributes are going to be loaded as well. with the @Basic annotation whose default fetch policy is FetchType.EAGER . This process takes place at build time, right after entity classes are compiled from their associated source files. When executing the following test case:� Stack Exchange network consists of 177 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

3. Lifecycle Callbacks, It is often necessary to perform various actions at different stages of a persistent object's lifecycle. PostLoad : Methods marked with this annotation will be invoked after all eagerly fetched fields of your class have been loaded from the� Doctrine Object Relational Mapper Documentation: Events . Naming convention. Events being used with the Doctrine 2 EventManager are best named with camelcase and the value of the corresponding constant should be the name of the constant itself, even with spelling.

PostLoad � Map � JPA Q&A, Execute @PostLoad _after_ eagerly fetching? stackoverflow.com. Using JPA2/ Hibernate, I've created an entity A that has a uni-directional mapping to an entity � As node name is unique and constant in the cluster, this insures that no conflict will appear at the creation level. For the time begin, DBA has no way to refine location of tablespace for a single node level but this will be added later with extra support of CREATE/DROP TABLESPACE through EXECUTE DIRECT.

We can have no reason for believing that, in this self-sustaining condition, the impression changes its seat, or passes into some new circles that have the special property of retaining it. Every part actuated _after_ the shock must have been actuated _by_ the shock, only more powerfully.

Comments
  • @PostLoad works great for me on hibernate 3.5.6, but other people do indeed suffer: opensource.atlassian.com/projects/hibernate/browse/HHH-6043
  • +1 for the bug report. I have similar problem and upgrading the Hibernate to the newest version 4.1.1 nor to 3.5.6 did not help.
  • @PostConstruct doesn't help. Although it gives a chance to the container to initialize stuff, the fields I need to be initialized are not set up by the Spring container. Since @PostConstruct is called immediately after the constructor, Hibernate has not even populated fields like @Id and such.