解决问题(十)——HashCodeBuilder在one-to-many关系中出现Lazy异常

为了识别po对象中,通常都会用po对象继承一个BaseObject基类,小弟也是如此做法,基类是从网上找到的一个比较好的范例。

public   class  BaseObject  implements  Serializable 
{
    
private   static   final   long  serialVersionUID  =   - 1540986753080346874L ;

    
public  String toString() 
    {
        
return  ToStringBuilder.reflectionToString( this , ToStringStyle.MULTI_LINE_STYLE);
    }
    
    
public   boolean  equals(Object o) 
    {
        
return  EqualsBuilder.reflectionEquals( this , o);
    }
    
    
public   int  hashCode() 
    {
        
return  HashCodeBuilder.reflectionHashCode( this );
    }
}

 

代码本身并没有什么问题,但是如果某个po对象包含关联属性,比如说Set,那么在进行懒加载后就会有以下异常。

org.hibernate.LazyInitializationException: illegal access to loading collection
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:
341 )
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:
86 )
    at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:
411 )
    at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:
856 )
    at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:
174 )
    at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:
348 )
    at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:
387 )
    at com.coolcate.model.BaseObject.hashCode(BaseObject.java:
33 )
    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 org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:
157 )
    at com.coolcate.model.vo.Restaurant$$EnhancerByCGLIB$$7e0832e8.hashCode(
< generated > )
    at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:
856 )
    at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:
174 )
    at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:
348 )
    at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:
387 )
    at com.coolcate.model.BaseObject.hashCode(BaseObject.java:
33 )
    at java.util.HashMap.put(HashMap.java:
418 )
    at java.util.HashSet.add(HashSet.java:
194 )
    at java.util.AbstractCollection.addAll(AbstractCollection.java:
318 )
    at org.hibernate.collection.PersistentSet.endRead(PersistentSet.java:
329 )
    at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:
237 )
    at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:
222 )
    at org.hibernate.engine.loading.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:
195 )
    at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:
877 )
    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:
865 )
    at org.hibernate.loader.Loader.doQuery(Loader.java:
729 )
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:
236 )
    at org.hibernate.loader.Loader.loadCollection(Loader.java:
1994 )
    at org.hibernate.loader.collection.BatchingCollectionInitializer.initialize(BatchingCollectionInitializer.java:
52 )
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:
565 )
    at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:
60 )
    at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:
1716 )
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:
344 )
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:
86 )
    at org.hibernate.collection.PersistentSet.toArray(PersistentSet.java:
171 )
    at com.coolcate.test.RestaurantTest.testSelectAllSubRestaurant(RestaurantTest.java:
55 )
    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:
168 )
    at junit.framework.TestCase.runBare(TestCase.java:
134 )
    at junit.framework.TestResult$
1 .protect(TestResult.java: 110 )
    at junit.framework.TestResult.runProtected(TestResult.java:
128 )
    at junit.framework.TestResult.run(TestResult.java:
113 )
    at junit.framework.TestCase.run(TestCase.java:
124 )
    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

 

对于具体原因,也不是很清楚。但是根据错误堆栈判断,是在构建hashCode时加入了关联属性,由此激活了懒加载。在我的测试代码中,在没有调用hashCodeBuilder之前已经激活了懒加载,之后又调用hashCodeBuilder引起二次加载,导致以上错误。这些没有什么依据,仅仅是推测。基于这个推测,我去掉了BaseObject,手动在每个po对象中重载equals和hashCode方法,方法中只是包含po对象的属性,不包含po对象所关联的集合类属性。这样就解决了问题。

你可能感兴趣的:(解决问题)