-->
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.  [ 3 posts ] 
Author Message
 Post subject: Just need an explanation
PostPosted: Tue Jul 16, 2013 9:22 am 
Newbie

Joined: Tue Jul 16, 2013 9:09 am
Posts: 3
Hello,

I started learning Hibernate (join with spring) for few days and I have a very simple question. I'm doing a unit test to be sure my different layers works well and I wonder about a collection loading problem. Here is a part of my spring+hibernate conf :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

   <!-- Hibernate session factory -->
   <bean id="sessionFactory"
      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

      <property name="dataSource">
         <ref bean="dataSource" />
      </property>

      <property name="hibernateProperties">
         <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
         </props>
      </property>

      <property name="annotatedClasses">
         <list>
            <value>com.nomia.onmap.model.Value</value>
            <value>com.nomia.onmap.model.Attribut</value>
            <value>com.nomia.onmap.model.BooleanValue</value>
            <value>com.nomia.onmap.model.Element</value>
            <value>com.nomia.onmap.model.LocString</value>
            <value>com.nomia.onmap.model.Map</value>
            <value>com.nomia.onmap.model.Picto</value>
            <value>com.nomia.onmap.model.Relation</value>
            <value>com.nomia.onmap.model.LocStringValue</value>
         </list>
      </property>

   </bean>

   <bean id="transactionManager"
      class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory" />
   </bean>

   <tx:annotation-driven transaction-manager="transactionManager" />

<context:component-scan  base-package="
   com.nomia.onmap.controller,
   com.nomia.onmap.service,
   com.nomia.onmap.dao"/>
</beans>



My unit test is like that :

Code:
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations="classpath:unittest-spring-all.xml") 
@TransactionConfiguration(defaultRollback=true,transactionManager="transactionManager") 
public class ElementHibernateDaoImplTest {

   private final static Log _log = LogFactory.getLog(ElementHibernateDaoImplTest.class);

   @Autowired 
   private ElementService elementService; 
   
   @Test 
   public void testCreateElement() { 
      Attribut att = new Attribut();
      ...
      
      Element element = new Element();
      element.getAttributs().add(att);
      
      elementService.save(element);
      assertNotNull(element.getId());
      
      _log.info("Number of attributs : "+element.getAttributs());
      for (Attribut attribut : element.getAttributs()) {
         _log.info(attribut);
      }

//Until here, everything works very well, no problem. Datas are registerd in database.
      
      Element elt = elementService.getElement(element.getId(), true);
      _log.info("Number of attributs : "+elt.getAttributs());//Here, I have an exception depending on what I write in my DAO (see just after please)
      for (Attribut attribut : elt.getAttributs()) {
         _log.info(attribut);
      }


As I explain in this code, I have sometimes an exception (org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.nomia.onmap.model.Element.attributs, could not initialize proxy - no Session) which I do not understand :-) Let me explain :

Here is my dao:
Code:
@Transactional(readOnly = true)
   public Element getElement(long elementId, boolean loadAttributs){
      Element element = (Element)sessionFactory.getCurrentSession().get(Element.class, elementId);
      if(loadAttributs){
         Set<Attribut> attributs = element.getAttributs();
         //_log.debug(attributs.size()+" attributs loadded");
      }
      return element;
   }


If I uncomment the _log.debug(attributs.size()+" attributs loadded"); line everything works well. But if I comment it (like now) i have the exception as I say in my unit test. However I thought that element.getAttributs() should be enought to load my collection as my session is open in this method.
So is there a better way to load my lazy collection than adding a log... What do I do wrong please ?

Thank's in advance !

Clement


Top
 Profile  
 
 Post subject: Re: Just need an explanation
PostPosted: Sat Jul 27, 2013 4:48 pm 
Newbie

Joined: Sat Jul 27, 2013 1:47 am
Posts: 5
By 'Lazy fetch', it means, that entities are loaded lazily whenever it is required/ or say accessed.
For loading entities, we need session object.

In your case, getElement method is a transactional one. So session lifecycle is only on that method.
So, after you come out of the method and when you try to access the lazy entities, it tries to find session object to interact with database to load those entities.
As session is no more, it throws exception.

Coming to the log statement, log statement access the lazy entity. During access, entities has been lazily loaded during that statement. Since session object is available inside the method, it has been successfully loaded without any problem.
Once the lazy entities are loaded, it will remain there for your access and thats how the lazy entities are being accessed without any problem if you have the log statement inside the method.

Thanks
Sathish Kannan


Top
 Profile  
 
 Post subject: Re: Just need an explanation
PostPosted: Sun Jul 28, 2013 4:22 am 
Newbie

Joined: Tue Jul 16, 2013 9:09 am
Posts: 3
Thanks for your answer, but I don't understand completely. I totally understand the fact that I nead a session to load the lazy entities. What I do not understand is why doing "Set<Attribut> attributs = element.getAttributs();" is not enought to load them ? I mean, I get lazy entities here so I thought it will be enought to load them in my "element" object, and then I could use them outside the method. I don't understand why it is not enought. Why do I need to do somethind like "_log.debug(attributs.size()+" attributs loadded");" more to really load my lazy entities and to use them outside my method. Why "Set<Attribut> attributs = element.getAttributs();" is not enought ?

Thank you very much !


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.