-->
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.  [ 9 posts ] 
Author Message
 Post subject: Why does hibernate fetch objects lazy on access?
PostPosted: Tue Oct 03, 2006 10:07 am 
Beginner
Beginner

Joined: Fri Apr 28, 2006 3:04 am
Posts: 22
Location: Amsterdam
Why does hibernate fetch objects lazy on access?

I can make this test, which in my opinion is kind of weird:

Code:
public void testTest()
{
   Region region = getRegionPersistent();
   regionDao.getHibernateTemplate().evict(region);
      
   Country c = null;
   try {
      c = countryDao.get(region.getId());   
      System.out.println("found ");
   } catch (Exception e) {
      e.printStackTrace();
      System.out.println("not found");
   }
   System.out.println(c.getName());
}


The purpose of this test was to insert a Subclass into the db, evict the object from the session so hibernate doesn't return that exact object. Then retrieve another subclass (with the same baseclass) from the db. The idea was to check if hibernate returns the baseclass, or the subclass, or gives an

Hibernate gives an exception which sais that he can't find the object (which is what we expected, because it does not exists).
The strange part is that the not found exception is thrown on the last line, in the system.out when we try to print the name of the object we fetched..

This is kind of strange, since we fetch some object with by Id, try catch if we can find it or not.. It prints "found", but when we actually use the object, suddenly it throws an exception... Is this a bug or a feature to improve performace or something?

Im using:
Hibernate-Version: 3.1.3
Hibernate Annotations Version: 3.1.0.Beta10
Spring-Version: 2.0-rc3

_________________
Greetz, Marcel - http://java-aap.blogspot.com


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 04, 2006 2:15 am 
Beginner
Beginner

Joined: Fri Apr 28, 2006 3:04 am
Posts: 22
Location: Amsterdam
Could it have something todo with the CGLIB enhancer which proxies my calls to the hibernate object..?

_________________
Greetz, Marcel - http://java-aap.blogspot.com


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 04, 2006 3:54 am 
Regular
Regular

Joined: Wed Jul 27, 2005 2:33 am
Posts: 118
Post the exception stacktrace that you are seeing and also the appropriate hbm file in use


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 04, 2006 4:09 am 
Beginner
Beginner

Joined: Fri Apr 28, 2006 3:04 am
Posts: 22
Location: Amsterdam
Code:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.nefli.camelot.data.domain.Country#145]
   at org.hibernate.ObjectNotFoundException.throwIfNull(ObjectNotFoundException.java:27)
   at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:65)
   at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:98)
   at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:158)
   at com.nefli.camelot.data.domain.Country$$EnhancerByCGLIB$$a5ef7b13.getName(<generated>)
   at com.nefli.camelot.data.dao.test.AssetDaoTest.testTest(AssetDaoTest.java:28)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)




thats the stacktrace, pretty straight forward. Cant post hbm files because it dont have any, i work with the EJB3.0 persistence annotations. But they are pretty plain forward and simple also. .

_________________
Greetz, Marcel - http://java-aap.blogspot.com


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 04, 2006 4:17 am 
Regular
Regular

Joined: Wed Jul 27, 2005 2:33 am
Posts: 118
Looks like your countryDAO's get method is eating up the exception thrown by Hibernate. Are you doing any exception handling in the countryDAO? If yes are you throwing back the exception from the DAO or just logging them in the DAO?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 04, 2006 4:21 am 
Senior
Senior

Joined: Tue Aug 23, 2005 8:52 am
Posts: 181
Use the Session.load method if you want non-existence to throw an exception. From the JavaDocs

Code:
public Object load(Class theClass,
                   Serializable id)
            throws HibernateException

    Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists.

    You should not use this method to determine if an instance exists (use get() instead). Use this only to retrieve an instance that you assume exists, where non-existence would be an actual error.


Session.get returns null or the actual object(or proxy) , so what you are seeing is correct.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 04, 2006 4:21 am 
Beginner
Beginner

Joined: Fri Apr 28, 2006 3:04 am
Posts: 22
Location: Amsterdam
The DAO does the exception handling and throwing a new (NotFound) exception

Code:
       
try
{
       return (REC)getHibernateTemplate().load( implClass, pk );
} catch( HibernateObjectRetrievalFailureException e )
{
   throw new NotFoundException( "load failed", e );
}


But that exception is never thrown like you can see in the test. Actually this throws the exception (which is showed above) in the test:

Code:
System.out.println(c.getName());

_________________
Greetz, Marcel - http://java-aap.blogspot.com


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 04, 2006 4:21 am 
Regular
Regular

Joined: Wed Jul 27, 2005 2:33 am
Posts: 118
The API get() on Hibernate Session mentions:

http://simoes.org/docs/hibernate-2.1/api/net/sf/hibernate/Session.html#get(java.lang.Class,%20java.io.Serializable)

Quote:
Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance. (If the instance, or a proxy for the instance, is already associated with the session, return that instance or proxy.)


Notice the sentence marked in bold, above. I believe, Hibernate is returing you a proxy instance associated with the Session and when you are invoking the getName method on the proxy, it is trying to find the object and on not finding it, its throwing the exception


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 04, 2006 4:25 am 
Beginner
Beginner

Joined: Fri Apr 28, 2006 3:04 am
Posts: 22
Location: Amsterdam
Yes it gives me a proxy to an object that isn't in the session anymore.. Thnx

_________________
Greetz, Marcel - http://java-aap.blogspot.com


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