Question

I have a Patient who has a Set of NeurologicalFinding medical records.

Patient class structure is as follows:

@Entity
@Table(name = "patient")
public class PatientEntity {

   //other properties

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "patient")
   private Set<NeurologicalFindingEntity> neurologicalFindingList;

   public Set<NeurologicalFindingEntity> getNeurologicalFindingList() {        
    return neurologicalFindingList; //DEBUGGER never got to this line
   }

   //other get and set methods
}

NeurologicalFinding class structure is as follows:

@Entity
@Table(name = "neurological_finding")
public class NeurologicalFindingEntity{

   //other properties

   @ManyToOne
   @JoinColumn(name = "patient_id")
   private PatientEntity patient;

   //get and set methods
}

In my app, I want to get a Patient by his ID without his NeurologicalFinding records with the following method of the DAO:

public PatientEntity getPatientById(int patientId) {      

   Criteria criteria = sessionFactory.getCurrentSession()
            .createCriteria(PatientEntity.class);

   criteria.add(Restrictions.eq("id", patientId));

   return (PatientEntity) criteria.uniqueResult();
}

When I use this method I still get patient WITH his NeurologicalFinding records. The getter of the collection is never called (checked with debuger), so how is it possible that the lazy collection is loaded when nobody asked for it?

If you need more info about my app I can provide you with it.

Was it helpful?

Solution

Try using hibernate.show_sql = true to print the queries and confirm if lazy loading is working or not:

   <bean id= "entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
         ...
         <property name="jpaProperties" >
               <props>
                     ...
                     <prop key="hibernate.show_sql" >true</ prop>
                     <prop key="hibernate.format_sql" >true</ prop>
                     <prop key="hibernate.use_sql_comments">true</prop>
          ...

use_sql_comments is especially important, as it will print a comment at the beginning of the query stating the reason why the query is written: one-to-many, named query name, criteria query text, etc.

Then by putting breakpoints it's possible to see if the collection is fetched at the moment you inspect it with the debugger.

If it's not the case, and the getter is not called, then it could be that the lazy loading is being triggered directly inside the class via direct access to the property neurologicalFindingList.

Are you accessing the property directly inside PatientEntity, for example in equals and hashcode? If so by removing it from the equals and hashcode the problem should be fixed.

OTHER TIPS

For one, you could use EntityManager.find() instead of a criteria query in this particular scenario. Secondly, you could try putting the annotation on the setter instead of the field. Thirdly, you can also specify fetch=LAZY on the other side of the relationship, but I don't think that's what you need.

Finally, what I found in my experience (although this applied to EclipseLink, not necessarily Hibernate) is that in order to support lazy fetching, sometimes bytecode weaving is required. Each JPA provider usually has a tool for that (along with an Ant task and a Maven plugin).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top