Hibernate version:
3.1
Hello everybody
I m using Hibernate with lazy loading option by default (CGLIB)
I try to test in a JUnit test link between a Pojo named "session" and a Pojo named "module"
I got this in my mappings file :
in my Module.hbm.xml
Code:
<many-to-one name="session" class="Session" column="ID_SESSI" not-null="true"/>
in my Session.hbm.xml
Code:
<set name="modules" inverse="true" cascade="all">
<key column="ID_SESSI"/>
<one-to-many class="Module"/>
</set>
A "session" can contains from 0 to many "modules".
In Pojo "session", i have
Code:
public Set getModules() {
return modules;
}
public void setModules(Set modules) {
this.modules = modules;
}
public void addModule(Module module){
if (!this.modules.contains(module)){
this.modules.add(module);
module.setSession(this);
}
}
public void removeModule(Module module){
if (this.modules.contains(module)){
this.modules.remove(module);
module.setSession(null);
}
}
In Pojo "module", i have
Code:
public Session getSession() {
return session;
}
public void setSession(Session session) {
if (this.session==null){
this.session = session;
if (this.session!=null){
if (!Hibernate.isInitialized(this.session.getModules())){
Hibernate.initialize(this.session.getModules());
}
this.session.addModule(this);
}
}
else if(!this.session.equals(session)){
this.session.removeModule(this);
this.session = session;
if (this.session!=null){
if (!Hibernate.isInitialized(this.session.getModules())){
Hibernate.initialize(this.session.getModules());
}
this.session.addModule(this);
}
}
}
In my test case i Have
Code:
//some code creating a "session" object
org.hibernate.Session sessionHibernate = HibernateUtil.getSessionFactory().getCurrentSession();
sessionHibernate.beginTransaction();
Session session = (Session)sessionHibernate.load(Session.class, idSession);
//at this point, all good : i can inspect the object and see CGLIB loaded...
//i tried with get instead of load...
Module module = new Module();
//some "stupid" setters for module
module.setSession(session);
At this point, I have this error :
Code:
org.hibernate.PropertyAccessException: Exception occurred inside setter of com.foederis.business.persistent.formation.Module.session
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:65)
at org.hibernate.tuple.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:330)
at org.hibernate.tuple.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:188)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3232)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:126)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1919)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:71)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:520)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1627)
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:454)
at org.hibernate.Hibernate.initialize(Hibernate.java:295)
at com.foederis.business.persistent.formation.Module.setSession(Module.java:119)
at com.foederis.business.persistent.formation.TestModule.testCreationModule(TestModule.java:113)
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:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
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 junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
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)
Caused by: java.lang.reflect.InvocationTargetException
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:324)
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:42)
... 31 more
Caused by: org.hibernate.AssertionFailure: force initialize loading collection
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:446)
at org.hibernate.Hibernate.initialize(Hibernate.java:295)
at com.foederis.business.persistent.formation.Module.setSession(Module.java:119)
... 36 more
The line indicated by Module.java:119 is the line
Code:
Hibernate.initialize(this.session.getModules());
in the Module.java setSession(..)
I don't understand why it block because in this setter :
- i look if the object is initialized (it isnt)
- i call initialize to be sure before requesting add a new object and here it seems my pojo isnt initialized but have already begun to load ...
I took a look to the source code, and it seem to be that... what can i do?