Insertion failure of a second entity in 1-N relationship when using PROPERTY access
instead of FIELD access
-----------------------------------------------------------------------------------------------------------
Key: HHH-5833
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5833
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.6.1
Environment: Windows XP, JUnit test under Eclipse with HSQLDB.
Reporter: Cyrille Charron
Attachments: FamilyModel.zip, Hibernate-bug.txt, HibernateTest.zip
While testing JBossCache, i have stumbled onto an apparent bug of Hibernate,
which throws a LazyInitializationException
on a 1-N bi-directional relation between an entity Address
and two entities Person.
NB: there's no bug when using OpenJPA.
I have copied an extract of my java code
and the stack trace with a breakpoint on the exception
at line 366 into AbstractPersistentCollection.java
at the end of this issue report.
If i am right, the bug arises because Hibernate tries to initialize
a collection which is already in the state of initialization.
This bug appears when i link 2 Person entities to the same Address entity
via 1-N bi-directional relation, and if the Person's setter updates
the 2 sides of this relation-ship by calling itself the Address's setter
(this "helper" code in entities was to be sure
that the relation is updated on both sides, whoever is the owner).
In my example, this collection is the "inhabitants" attribute
of my entity Address, in which i try to add a second entity Person,
which has an attribute "address" pointing on the entity Address.
Here is the "helper" code of the Person's setter :
{code}
public boolean setAddress(Address address) {
boolean done = false;
if (this.address != address) {
if (this.address != null) this.address.remInhabitant(this);
this.address = address;
if (this.address != null) this.address.addInhabitant(this);
done = true;
}
return done;
}
{code}
My Stateless Session Bean had only to update one side of the relation :
{code}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void setAddressForPerson(int personId, int addressId) {
Address address = findAddress(addressId);
Person person = findPerson(personId);
...
person.setAddress(address);
}
{code}
In the stack trace we see that :
we call Person.setAddress(Address) on my SECOND entity Person
which calls PersistentSet.size() on Address's collection
which calls PersistentSet(AbstractPersistentCollection).initialize(boolean)
which calls TwoPhaseLoad.initializeEntity
which calls PojoEntityTuplizer.setPropertyValues
which calls Person.setAddress(Address) on my FIRST entity Person
which calls PersistentSet.size() on Address's collection
which calls PersistentSet(AbstractPersistentCollection).initialize(boolean)
which throws the LazyInitializationException
as if the relation between my FIRST entity Person and entity Address
has not finished its initialization.
This bug DISAPPEARS if i delete the "helper" code from my entity Person :
{code}
public boolean setAddress(Address address) {
this.address = address;
return true;
}
{code}
and if i update manually the both sides of the relation in my Session Bean :
{code}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void setAddressForPerson(int personId, int addressId) {
Address address = findAddress(addressId);
Person person = findPerson(personId);
...
if (person.getAddress() != null) person.getAddress().remInhabitant(person);
if (address != null) address.addInhabitant(person);
person.setAddress(address);
}
{code}
I join 3 files :
the model project (entities Person, Address and Family)
the test project (Bean and JUnit)
a resume of source code and the stack trace with some variables values.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira