Commit fails when an explicit flush called before
-------------------------------------------------
Key: HHH-6810
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-6810
Project: Hibernate Core
Issue Type: Bug
Components: entity-manager
Affects Versions: 3.6.5
Environment: Hibernate 3.6.5 / HSQLDB 1.8.0.10
Reporter: Marek Matczak
Attachments: hibernate.properties, SomeItem.java, SomeOtherThing.java,
SomeUser.java, test-case.zip
We have a simple model: SomeUser may have SomeItems (one-to-many relationship);
SomeOtherThing is related neither to SomeUser nor to SomeItem (see the attached files for
details).
We register a pre insert event listener in which SomeOtherThings are queried when a new
SomeUser is inserted:
{code:title=SomeUserPreInsertEventListenerQueryingSomeOtherThings.java|borderStyle=solid}
public class SomeUserPreInsertEventListenerQueryingSomeOtherThings implements
PreInsertEventListener {
private static final long serialVersionUID = 7457725085286340589L;
public boolean onPreInsert(PreInsertEvent event) {
Class<? extends Object> currentClass = event.getEntity().getClass();
if (SomeUser.class.equals(currentClass)) {
event.getSession().createCriteria(SomeOtherThing.class).list();
}
return false;
}
}
{code}
When we try to insert some data, the following code fails:
{code:title=Test.java|borderStyle=solid}
Configuration cfg = new Configuration() // hibernate.properties is loaded here
.addAnnotatedClass(SomeUser.class) //
.addAnnotatedClass(SomeItem.class) //
.addAnnotatedClass(SomeOtherThing.class);//
cfg.getEventListeners().setPreInsertEventListeners(
new PreInsertEventListener[] { new
SomeUserPreInsertEventListenerQueryingSomeOtherThings() });
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
SomeUser user = new SomeUser();
user.setName("Some name");
session.save(user);
SomeItem item = new SomeItem();
item.setDescription("Some description");
user.addItem(item);
session.save(item);
// for some reason we want to call a flush here
session.flush(); // 1st flush
session.getTransaction().commit(); // 2nd flush
{code}
Our analysis shown that the 1st flush (which triggers the
SomeUserPreInsertEventListenerQueryingSomeOtherThings) left the persistence context in
some illegal state so that the commit (which issues another flush) fails:
org.hibernate.HibernateException: Found two representations of same collection:
bug.report.model.SomeUser.items
at org.hibernate.engine.Collections.processReachableCollection(Collections.java:175)
at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:60)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:122)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:83)
at
org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:77)
at
org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:165)
at
org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)
at
org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
at
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
If we either didn't call the 1st flush or didn't register the event listener at
all, the code would succeed.
--
This message is automatically generated by JIRA.
For more information on JIRA, see:
http://www.atlassian.com/software/jira