-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: why FetchMode.EAGER doesnt work? I used a tricky workaround!
PostPosted: Mon Aug 21, 2006 5:00 am 
Beginner
Beginner

Joined: Sat Oct 08, 2005 2:13 am
Posts: 47
Hello
I have an Entity namely "OtherProviders" with a join with two other entity "MedicalService" and "HealthProvider" that each entity has a list with the names "medicalServiceLocales" and "healthProviderLocales".
when I select from OtherProviders, I want to load both "medicalServiceLocales" and "healthProviderLocales" eagerly, not lazily.
but the FetchMode of criteria doesnt work.

here is my code

Code:
   public List<OtherProviders> select(LocaleSelector selector,Integer patientId,String fromDate, String toDate,List<Integer> providerId,List<Integer> serviceId )throws NoDataAvailableException {
      Session session = getSession();
      Criteria criteria = session.createCriteria(OtherProviders.class);
      
      if(patientId == null || patientId == 0)
         throw new IllegalArgumentException("patient Id should not be null or with zero value :'" + patientId+"'");
      
      criteria.add(Expression.eq("patientInfoId",patientId));
      
      if(fromDate != null && !fromDate.equals(""))
         criteria.add(Expression.ge("admitDate",fromDate));
      
      if(toDate != null && !toDate.equals(""))
         criteria.add(Expression.le("admitDate",toDate));

      if(providerId != null && providerId.size() > 0)
         criteria.add(Expression.in("healthProviderId",providerId));

      if(serviceId != null && serviceId.size() > 0)
         criteria.add(Expression.in("medicalServiceId",serviceId));
      
      
criteria.add(Expression.eq("medicalServiceLocales.localeId",selector));
   criteria.setFetchMode("medicalService.medicalServiceLocales",FetchMode.EAGER);

      criteria.createCriteria("healthProvider","healthProvider")
      .createAlias("healthProviderLocales","healthProviderLocales")
      .add(Expression.eq("healthProviderLocales.localeId",selector))
      .setFetchMode("healthProvider.healthProviderLocales",FetchMode.JOIN);
      
      criteria.createCriteria("medicalService","medicalService")
      .createAlias("medicalServiceLocales","medicalServiceLocales")
      .add(Expression.eq("medicalServiceLocales.localeId",selector))
      .setFetchMode("medicalService.medicalServiceLocales",FetchMode.JOIN);

      List<OtherProviders> list = criteria.list();
      releaseSession(session);
      return list;
   }


eventually, after testing and trying many ways, I choosed a tricky way:
Code:
        .....
        .....
      List<OtherProviders> list = criteria.list();
      for(OtherProviders op:list) {
         int i = 0;
         for(MedicalServiceLocale msl : op.getMedicalService().getMedicalServiceLocales())
            i++;
         for(HealthProviderLocale hpl : op.getHealthProvider().getHealthProviderLocales())
            i++;
      }

      releaseSession(session);
      return list;



I know this workaround is weird, but I had to do it. please help me out to correct this.
any help will be appreciated.



Using Spring 2.0
Hibernate version: 3.1

Mapping documents: Hibernate Annotation


Full stack trace of any exception that occurs:
(hibernate.LazyInitializationException 19 ) failed to lazily initialize a collection of role: com.payvand.hl7.model.domainobject.MedicalService.medicalServiceLocales, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.payvand.hl7.model.domainobject.MedicalService.medicalServiceLocales, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:246)
at com.payvand.hl7.model.dao.OtherProviderDAOTest.testProvinceLocale(OtherProviderDAOTest.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)


Name and version of the database you are using: MySql 4

The generated SQL (show_sql=true):
Hibernate: select this_.id as id13_7_, this_.medical_service_id as medical7_13_7_, this_.admit_date as admit2_13_7_, this_.health_provider_id as health9_13_7_, this_.deleted as deleted13_7_, this_.status_code as status4_13_7_, this_.admit_time as admit5_13_7_, this_.discharge_date as discharge6_13_7_, this_.patient_info_id as patient8_13_7_, this_.admit_type as admit10_13_7_, medicalser3_.id as id16_0_, medicalser3_.deleted as deleted16_0_, medicalser3_.status_code as status3_16_0_, medicalser3_.webservice_url as webservice4_16_0_, medicalser4_.locale_id as locale1_17_1_, medicalser4_.medical_service_id as medical2_17_1_, medicalser4_.name as name17_1_, healthprov1_.id as id11_2_, healthprov1_.medical_service_type as medical2_11_2_, healthprov1_.url as url11_2_, healthprov1_.deleted as deleted11_2_, healthprov1_.status_code as status5_11_2_, healthprov1_.id_city as id6_11_2_, healthprov1_.id_parent as id7_11_2_, healthprov1_.permission_type as permission8_11_2_, healthprov1_.telecom as telecom11_2_, healthprov1_.webservice_url as webservice10_11_2_, users9_.user_name as user1_9_3_, users9_.password as password9_3_, users9_.position as position9_3_, users9_.id_health_provider as id7_9_3_, users9_.status_code as status4_9_3_, users9_.id_city as id5_9_3_, users9_.assistant as assistant9_3_, users9_.mobile_contact as mobile8_9_3_, users9_.nurse as nurse9_3_, users9_.obstetrician as obstetr10_9_3_, users9_.phone_no1 as phone11_9_3_, users9_.phone_no2 as phone12_9_3_, users9_.speciality as speciality9_3_, users9_.surgeon as surgeon9_3_, users9_.technician as technician9_3_, users9_.upin as upin9_3_, users9_.enabled as enabled9_3_, city10_.id as id2_4_, city10_.id_country as id2_2_4_, city10_.id_province as id3_2_4_, city10_.status_code as status4_2_4_, healthprov2_.locale_id as locale1_12_5_, healthprov2_.id_health_provider as id2_12_5_, healthprov2_.address as address12_5_, healthprov2_.name as name12_5_, patientinf12_.id as id14_6_, patientinf12_.identity_no as identity2_14_6_, patientinf12_.deleted as deleted14_6_, patientinf12_.status_code as status4_14_6_, patientinf12_.mobile_contact as mobile5_14_6_, patientinf12_.birth_time as birth6_14_6_, patientinf12_.covered_party_exp_date as covered7_14_6_, patientinf12_.deceased_ind as deceased8_14_6_, patientinf12_.deceased_time as deceased9_14_6_, patientinf12_.email as email14_6_, patientinf12_.gender as gender14_6_, patientinf12_.id_birth_city as id12_14_6_, patientinf12_.last_covered_party_id as last13_14_6_, patientinf12_.last_home_phone1 as last14_14_6_, patientinf12_.last_home_phone2 as last15_14_6_, patientinf12_.last_insurance_no as last16_14_6_, patientinf12_.last_living_city as last17_14_6_, patientinf12_.last_living_district as last18_14_6_, patientinf12_.last_living_post_code as last19_14_6_, patientinf12_.national_code as national20_14_6_, patientinf12_.provider_org as provider21_14_6_, patientinf12_.race as race14_6_, patientinf12_.religious_affiliation as religious23_14_6_ from otherProviders this_ inner join medicalService medicalser3_ on this_.medical_service_id=medicalser3_.id inner join medicalServiceLocale medicalser4_ on medicalser3_.id=medicalser4_.medical_service_id inner join healthProvider healthprov1_ on this_.health_provider_id=healthprov1_.id left outer join users users9_ on healthprov1_.id=users9_.id_health_provider left outer join city city10_ on healthprov1_.id_city=city10_.id inner join healthProviderLocale healthprov2_ on healthprov1_.id=healthprov2_.id_health_provider left outer join patientInformation patientinf12_ on this_.patient_info_id=patientinf12_.id where this_.patient_info_id=? and healthprov2_.locale_id=? and medicalser4_.locale_id=?
Hibernate: select country0_.id as id6_1_, country0_.c2code as c2_6_1_, country0_.c3code as c3_6_1_, countryloc1_.id_country as id2_3_, countryloc1_.locale_id as locale1_3_, countryloc1_.locale_id as locale1_7_0_, countryloc1_.id_country as id2_7_0_, countryloc1_.name as name7_0_, countryloc1_.nationality as national4_7_0_ from country country0_ left outer join counttylocale countryloc1_ on country0_.id=countryloc1_.id_country where country0_.id=?
Hibernate: select province0_.id as id4_3_, province0_.id_country as id2_4_3_, country1_.id as id6_0_, country1_.c2code as c2_6_0_, country1_.c3code as c3_6_0_, countryloc2_.id_country as id2_5_, countryloc2_.locale_id as locale1_5_, countryloc2_.locale_id as locale1_7_1_, countryloc2_.id_country as id2_7_1_, countryloc2_.name as name7_1_, countryloc2_.nationality as national4_7_1_, provincelo3_.id_province as id2_6_, provincelo3_.locale_id as locale1_6_, provincelo3_.locale_id as locale1_5_2_, provincelo3_.id_province as id2_5_2_, provincelo3_.name as name5_2_ from province province0_ left outer join country country1_ on province0_.id_country=country1_.id left outer join counttylocale countryloc2_ on country1_.id=countryloc2_.id_country left outer join provincelocale provincelo3_ on province0_.id=provincelo3_.id_province where province0_.id=?
Hibernate: select users0_.user_name as user1_9_5_, users0_.password as password9_5_, users0_.position as position9_5_, users0_.id_health_provider as id7_9_5_, users0_.status_code as status4_9_5_, users0_.id_city as id5_9_5_, users0_.assistant as assistant9_5_, users0_.mobile_contact as mobile8_9_5_, users0_.nurse as nurse9_5_, users0_.obstetrician as obstetr10_9_5_, users0_.phone_no1 as phone11_9_5_, users0_.phone_no2 as phone12_9_5_, users0_.speciality as speciality9_5_, users0_.surgeon as surgeon9_5_, users0_.technician as technician9_5_, users0_.upin as upin9_5_, users0_.enabled as enabled9_5_, healthprov1_.id as id11_0_, healthprov1_.medical_service_type as medical2_11_0_, healthprov1_.url as url11_0_, healthprov1_.deleted as deleted11_0_, healthprov1_.status_code as status5_11_0_, healthprov1_.id_city as id6_11_0_, healthprov1_.id_parent as id7_11_0_, healthprov1_.permission_type as permission8_11_0_, healthprov1_.telecom as telecom11_0_, healthprov1_.webservice_url as webservice10_11_0_, city2_.id as id2_1_, city2_.id_country as id2_2_1_, city2_.id_province as id3_2_1_, city2_.status_code as status4_2_1_, city3_.id as id2_2_, city3_.id_country as id2_2_2_, city3_.id_province as id3_2_2_, city3_.status_code as status4_2_2_, country4_.id as id6_3_, country4_.c2code as c2_6_3_, country4_.c3code as c3_6_3_, province5_.id as id4_4_, province5_.id_country as id2_4_4_ from users users0_ left outer join healthProvider healthprov1_ on users0_.id_health_provider=healthprov1_.id left outer join city city2_ on healthprov1_.id_city=city2_.id left outer join city city3_ on users0_.id_city=city3_.id left outer join country country4_ on city3_.id_country=country4_.id left outer join province province5_ on city3_.id_province=province5_.id where users0_.id_city=?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 5:30 am 
Expert
Expert

Joined: Thu Sep 22, 2005 10:29 am
Posts: 285
Location: Almassera/Valencia/Spain/EU/Earth/Solar system/Milky Way/Local Group/Virgo Supercluster
Why do you say that FetchMode.EAGER doesn't work?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 7:30 am 
Senior
Senior

Joined: Tue Mar 09, 2004 2:38 pm
Posts: 141
Location: Lowell, MA USA
First of all, FetchMode.EAGER has been deprecated sinev Hibernate 3.0, you should be using FetchMode.JOIN in it's place:

http://www.hibernate.org/hib_docs/v3/ap ... hMode.html

Second, it looks like you're closing your Session way too early. I'm not sure if, or how, Spring manages a Hibernate SessionFactory. I generally use a JTA Session Context, of if I'm not, I used the ThreadLocalSession and I set my transaction boundries outside of the DAO. So the flow might be something like so:

Code:
Transaction tx = getCurrentSession().beginTransaction();
List<OtherProviders> otherProviders = dao.select(...);
for(OtherProviders provider : otherProviders) {
   doSomething(provider)
}
tx.commit():


When using a current session context like this, you make better use of the Session cache and Hibernate will not issue addional SQL for rows it may have already loaded. Openning and closing multiple Sessions, like you would a java.sql.Connection, is not good for performance.

Right now, your Criteria is most likely returning a list of unitinialized proxies and you close the session just after you get the results. When you added in your fix, you actuall initialized all of the proxies in the list before you returned the results to the caller. Hope this helps.

Ryan-

_________________
Ryan J. McDonough
http://damnhandy.com

Please remember to rate!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 8:30 am 
Beginner
Beginner

Joined: Sat Oct 08, 2005 2:13 am
Posts: 47
damnhandy,

I used FetchMode.JOIN, SELECT and EAGER. but neither of them works.
I closed the session just after getting the list, because getSession() method doesnt return a Spring managed session, so i f I dont close that session after some query, it reach the maximum connection and the application wont work any longer. additionally, this is an enterprise application, if I dont release the session there isnt any other place to release it. because everything here managed by Spring framework.
Spring only provides a getHibernateTemplate() method and unfortunately it can not create a Criteria.

I dont have any transaction here, it is just a pure "select". I just want my lists being populated with data.

thank you very much indeed for your reply.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 21, 2006 8:31 am 
Beginner
Beginner

Joined: Sat Oct 08, 2005 2:13 am
Posts: 47
damnhandy,

I used both FetchMode.JOIN and EAGER. but neither of them works.
I closed the session just after getting the list, because getSession() method doesnt return a Spring managed session, so i f I dont close that session after some query, it reach the maximum connection and the application wont work any longer. additionally, this is an enterprise application, if I dont release the session there isnt any other place to release it. because everything here managed by Spring framework.
Spring only provides a getHibernateTemplate() method and unfortunately it can not create a Criteria.

I dont have any transaction here, it is just a pure "select". I just want my lists being populated with data.

thank you very much indeed for your reply.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 11, 2006 5:35 am 
Expert
Expert

Joined: Tue Dec 28, 2004 7:02 am
Posts: 573
Location: Toulouse, France
As said previously. No need to test FetchMode.JOIN and FetchMode.EAGER to test if there's a different behaviour. Same for SELECT and LAZY.

To convince you, look at the FetchMode class code :
Code:
   /**
    * Default to the setting configured in the mapping file.
    */
   public static final FetchMode DEFAULT = new FetchMode("DEFAULT");

   /**
    * Fetch using an outer join. Equivalent to <tt>fetch="join"</tt>.
    */
   public static final FetchMode JOIN = new FetchMode("JOIN");
   /**
    * Fetch eagerly, using a separate select. Equivalent to
    * <tt>fetch="select"</tt>.
    */
   public static final FetchMode SELECT = new FetchMode("SELECT");

   /**
    * Fetch lazily. Equivalent to <tt>outer-join="false"</tt>.
    * @deprecated use <tt>FetchMode.SELECT</tt>
    */
   public static final FetchMode LAZY = SELECT;
   /**
    * Fetch eagerly, using an outer join. Equivalent to
    * <tt>outer-join="true"</tt>.
    * @deprecated use <tt>FetchMode.JOIN</tt>
    */
   public static final FetchMode EAGER = JOIN;


You can see that putting EAGER is actually using JOIN, and LAZY is actually using SELECT...

Actually, I think there's a problem in the javadoc, asserting that SELECT is fetching "eagerly" :-/. BTW I post a comment about it on an issue in the jira (http://opensource.atlassian.com/project ... se/HHH-980).

_________________
Baptiste
PS : please don't forget to give credits below if you found this answer useful :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.