I've downloade the last version 3.2.5.GA.
I have a similar problem, it seems the cause is that we are not allowed to do any EM operations in a Persistence listener:
http://forum.hibernate.org/viewtopic.ph ... 67#2361167
Can someone explain why???
It still happens even after the fix bundeled with the 3.2.4
http://opensource.atlassian.com/project ... se/HHH-511
Code:
javax.persistence.RollbackException: Error while commiting the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:71)
at main.JPAMain.save(JPAMain.java:46)
at main.JPAMain.main(JPAMain.java:19)
Caused by: org.hibernate.HibernateException: Found two representations of same collection: fr.into.tests.Person.archiveList
at org.hibernate.engine.Collections.processReachableCollection(Collections.java:153)
at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:37)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
My code is under 3.2.3.GA:
a listener
Code:
@PreUpdate
public void updating(Archivable<T, P> source) {
System.out.println( "Updating " + source.getEntry().getNote() +" id: "+ source.getId() );
if( !source.getEntry().isLastOccurence() )
throw new UnsupportedOperationException( "You can't archive archived objects (other than original inserts)" + source );
EntityManager em = getEntityManager();
// must clear to avoid getting the same instance as archivable (from cache)
em.clear();
T toArchive = (T) em.find( source.getClass(), source.getId() );
toArchive.setId( 0 );
ArchivePointer<T> archivePointer = source.createArchiveRecord( toArchive );
toArchive.setArchivePointer( archivePointer );
toArchive.getEntry().setLastOccurence( false );
// must clear to oblige hibernate to insert a new row (elwhere even calling
// persist attempts an update)
em.clear();
toArchive.removeRelationships();
//FIXME remove
toArchive.getEntry().setNote( "archive" );
System.out.println( "Inserting old archive values with id number: " + toArchive.getId() );
em.persist( toArchive );
// no more clear needed: archivable and old are distinct instances.
}
and the method that fires the event's code (it happens on the second save that calls em.merge().
Code:
public static void main(String[] args) throws NamingException {
save( false );
save( true );
}
private static void save(boolean update) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory( "IntoJPA" );
EntityManager em = emf.createEntityManager();
try {
EntityTransaction transaction = em.getTransaction();
transaction.begin();
Person zied;
if( update )
zied = em.find( Person.class, 1L );
else
zied = new Person();
zied.getEntry().setNote( update ? "second" : "first" );
zied.getEntry().setStartDate( new Date() );
JPAMain.EM.set( em );
if( update ) {
System.out.println( "Updating Person: " + zied.getEntry().getNote() );
em.merge( zied );
} else {
System.out.println( "Inserting Person: " + zied.getEntry().getNote() );
em.persist( zied );
}
transaction.commit();
} catch( Exception ex ) {
ex.printStackTrace();
} finally {
em.close();
emf.close();
}
}