Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
Overview:
I am using detached objects (incorrectly) and hoping someone can offer some guidance. I have an object that has a collection of children (in this case it's the same type but that is irrelevant). I create the parent and the children, and cache the child as a detached object. In a new session, I wish to get the parent back and see if it has the child in it's collection. I have created a pretty simple test class here. Please advise where I am being stupid! Cheers
Hibernate version: 3.1.3
Mapping documents:
Code:
<hibernate-mapping>
<class table="node" name="org.gbif.Node">
<id column="id" unsaved-value="null" access="property" name="id">
<generator class="native"/>
</id>
<property name="name" not-null="false" access="property" column="name"/>
<many-to-one not-null="false" column="parent_id" access="property" cascade="save-update" name="parent"/>
<set access="property" lazy="true" inverse="true" cascade="save-update" name="children">
<key column="parent_id"/>
<one-to-many class="org.gbif.Node"/>
</set>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
try {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
// CREATE A CHILD NODE IN A SESSION
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Node child = new Node();
child.setName("child");
session.save(child);
session.flush();
tx.commit();
session.close();
// CREATE A PARENT NODE IN A SESSION
session = sessionFactory.openSession();
tx = session.beginTransaction();
Node parent = new Node();
parent.addChild(child);
parent.setName("parent");
session.save(parent);
session.flush();
tx.commit();
session.close();
// NOW SEE IF IT CAN BE COMPARED WITH THE DETACHED CHILD...
session = sessionFactory.openSession();
tx = session.beginTransaction();
parent = (Node) session.load(Node.class, parent.getId());
for (Node item : parent.getChildren()) {
log.info("Contains: " + item.id);
}
// None of these work...
// session.merge(child);
// session.lock(child, LockMode.NONE);
if (parent.getChildren().contains(child)) {
log.info("Parent has child with id " + child.getId());
} else {
log.info("Parent has NO child with id " + child.getId());
log.info("So going to add it now (expect a bang....)");
parent.addChild(child);
session.flush();
tx.commit();
}
session.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
Full stack trace of any exception that occurs:
Quote:
ERROR [SessionProblem] a different object with the same identifier value was already associated with the session: [org.gbif.Node#22]
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.gbif.Node#22]
at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:592)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:258)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:216)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:501)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:134)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:290)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:185)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:160)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:130)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:121)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:905)
at org.gbif.SessionProblem.main(SessionProblem.java:57)
Name and version of the database you are using:Mysql 5
The generated SQL (show_sql=true):Quote:
Hibernate: insert into node (name, parent_id) values (?, ?)
Hibernate: insert into node (name, parent_id) values (?, ?)
Hibernate: update node set name=?, parent_id=? where id=?
Hibernate: select node0_.id as id0_0_, node0_.name as name0_0_, node0_.parent_id as parent3_0_0_ from node node0_ where node0_.id=?
Hibernate: select children0_.parent_id as parent3_1_, children0_.id as id1_, children0_.id as id0_0_, children0_.name as name0_0_, children0_.parent_id as parent3_0_0_ from node children0_ where children0_.parent_id=?
Debug level Hibernate log excerpt:
Can post but think enough info above