-->
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.  [ 4 posts ] 
Author Message
 Post subject: Don't Let Hibernate Steal Your Identity --> LazyInitializ
PostPosted: Sun Aug 24, 2008 3:50 pm 
Newbie

Joined: Sun Aug 24, 2008 3:21 pm
Posts: 8
Hi.
My Hibernateversion 3.2.6.ga

I have a problem with Objectidenty, have read a article at OnJava.com "Don't Let Hibernate Steal Your Identity" and some Threads at this Forum.
Now i have refactored my Application like the suggestion at OnJava. The result is, i can't load my traversal Hierarchie of region and get a
If i debug my JUnit, i see, the parentId of my loaded region is not set with the databasevalue.
Exception as following:
Code:
DEBUG: de.myApp.bean.Region - getParentList()de.myApp.bean.Region@cfb11f[name=Deutschland,leftValue=<null>,rightValue=<null>]
ERROR: org.hibernate.LazyInitializationException - could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
   at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
   at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
   at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
   at de.myApp.bean.Region$$EnhancerByCGLIB$$9e36b7cd.hashCode(<generated>)
   at de.myApp.bean.Region.internalGetParentList(Region.java:82)
   at de.myApp.bean.Region.getParentList(Region.java:65)
   at de.myApp.test.service.RegionServiceDaoTest.testLoadRegionById(RegionServiceDaoTest.java:30)
   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:164)
   at junit.framework.TestCase.runBare(TestCase.java:130)
   at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:76)
   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:120)
   at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)


my Hibernateconfig:
Code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
    <class name="de.myApp.bean.Region" table="region">
      <id name="oid" type="java.lang.String">
         <column name="oid" />
         <generator class="assigned" />
      </id>
      <version name="version" column="VERSION"
        unsaved-value="null" />
        <property name="name" type="java.lang.String">
            <column name="NAME" length="155" not-null="true" />
        </property>
        <property name="leftValue" type="java.lang.Integer">
            <column name="leftvalue" />
        </property>
        <property name="rightValue" type="java.lang.Integer">
            <column name="rightvalue" />
        </property>
      <many-to-one name="parent" class="de.myApp.bean.Region" >
            <column name="parent_id"  />
      </many-to-one>       
      ..
      ..



my AbstractPersistenzobject:
Code:
   
public abstract class AbstractPersistentObject implements PersistentObject {

   
   private static final Log LOGGER = LogFactory.getLog(AbstractPersistentObject.class);
   private String oid = IdGenerator.createId();;
   private Integer version;
   
   public final String getOid() {
      return oid;
   }

   public final void setOid(String oid) {
      this.oid = oid;
   }

   public boolean equals(Object o) {
      if (this == o)
         return true;
      if (o == null || !(o instanceof PersistentObject)) {

         return false;
      }

      PersistentObject other = (PersistentObject) o;

      // if the id is missing, return false
      if (oid == null)
         return false;

      // equivalence by id
      return oid.equals(other.getOid());
   }

   public int hashCode() {
      if (oid != null) {
         return oid.hashCode();
      } else {
         return super.hashCode();
      }
   }

   public String toString() {
      return this.getClass().getName() + "[id=" + oid + "]";
   }
   
   public Integer getVersion() {
        return version;
    }
    public void setVersion(Integer version) {
        this.version = version;
    }


PersitenzObject
Code:
     
public interface PersistentObject {
   public String getOid();
    public void setOid(String oid);
    public Integer getVersion();
    public void setVersion(Integer version);
}


my Bean region
Code:
     
public class Region extends AbstractPersistentObject implements java.io.Serializable, PreorderModifiedTreeTraversal {

   public Region(){
      super();
   }
   public static final String ROOTREGION_ID = "1";
   static final long serialVersionUID = 4086461538561865983L;
   public final static Log LOGGER = LogFactory.getLog(Region.class);
   private String name;
     private Long anzahlitems;
     private Region parent;
   ..
   ..
   ..
   some more attributes and the getter/setter.


dao:
Code:
     
   public Region findByName(String regionName) {
      Criteria myCriteria=null;
      if (StringUtils.isNotBlank(regionName)) {
         myCriteria = getSession().createCriteria(Region.class);
         myCriteria.add(Restrictions.sqlRestriction("name = upper(?)", regionName, Hibernate.STRING));
      }
      List retval = myCriteria.list();
      if (retval.size()>0) {
         return (Region)retval.get(0);
      } else {
         return findRootRegion();
      }      
   }


my Junit:
Code:
     
   public void testLoadRegionById() throws Exception{
      regionDAO = (RegionDAO)applicationContext.getBean("regionDAO");
      
      Region region = regionService.getByName("Deutschland");
      Collection parents = region.getParentList();
      int i = 0;
   }


I believe my problem is the implementation of equals and hashcode within my abstract class. But i cannot see the mistake.
If i load the first region with name "Deutschland" in the debugmode i see, the parent_id of the parent (Europa with oid=1) isn't set and has the default value of the IdGenerator.
I can not understand why hibernate sets not the parent_id.

Thanks for your help.
alex


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 25, 2008 6:04 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
1. the mentioned article on itself isn't very good. For more complete information on the issue I'd recommend: http://www.hibernate.org/109.html

2. your problem is that you don't have a session for some LazyInitialization to work with. Read up on session handling and Lazy Loading.

You are trying to access stuff that isn't loaded yet, but you already closed the session you used to load your entity so it now can't complete its information. Hence the exception.

3. The behaviour of your debugger is annoying but normal. Since the property (id) is not yet loaded it shows up in the debuger as NULL. On access via the getter Hibernate will intercept the call and retrieve the necessary information, thus the getter will work as expected.

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 26, 2008 9:50 am 
Newbie

Joined: Sun Aug 24, 2008 3:21 pm
Posts: 8
schauder wrote:
1. the mentioned article on itself isn't very good. For more complete information on the issue I'd recommend: http://www.hibernate.org/109.html

Thanks. But i have read this article before i have created this Thread. In my option the article was very helpful. Also the discussion at the end of the http://www.hibernate.org/109.html article.


Quote:
2. your problem is that you don't have a session for some LazyInitialization to work with. Read up on session handling and Lazy Loading.


No. I develope a wepapp with springframework, SpringWebFlow, hibernate, JSF and facelet. The problem was, i lost the values of the superclass within the renderphase. Maybe a hibernate bug or a SpringWebFlow Bug.
I can't find the point where my objects are changed (the value of oid and version lost. My Object are no Proxies!!).
Inside the renderphase i see that the values from the superclass are null. My breakpoint inside the Constructor are never called. I believe there is a Bytecodemanipulation working.
If i move the attribute oid and version from superclass to region, my application runs.. Straight!
Quote:
3. The behaviour of your debugger is annoying but normal. Since the property (id) is not yet loaded it shows up in the debuger as NULL. On access via the getter Hibernate will intercept the call and retrieve the necessary information, thus the getter will work as expected.

[/quote]
correct. The Proxy is only a superclass of my bean and hold the values of the target bean inside the callback.


But, where is manipulating my objects?
Maybe, hibernate was it not.

alex


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 26, 2008 10:54 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
spring_alex wrote:
My Object are no Proxies!!


from the stack trace posted above:

spring_alex wrote:

at de.myApp.bean.Region$$EnhancerByCGLIB$$9e36b7cd.hashCode(<generated>)


Looks pretty much like a proxy

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


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