爲了識別po對象中,通常都會用po對象繼承一個BaseObject基類,小弟也是如此做法,基類是從網上找到的一個比較好的範例。
{
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,那麼在進行懶加載後就會有以下異常。
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對象所關聯的集合類屬性。這樣就解決了問題。