I’m trying to add a pojo to a collection in another pojo. I’m sure I’m making a really stupid mistake somewhere along the lines but I can’t figure out how to solve it.
I have a pojo LookupTable which contains a list of Columns:
public class LookupTable { private long id; // More properties go here... private List<Column> columns; public void addColumn(Column column) { this.columns.add(column); } // More methods go here... }
In my hibernate configuration I have:
<class name='LookupTable' table='ARR_LOOKUP_TABLE'> <id name='id' column='ID'> <generator class='native'/> </id> <!-- Some properties here --> <bag name='columns' cascade='all,delete-orphan' access='field'> <key column='LOOKUP_TABLE' not-null='true'/> <one-to-many class='Column'/> </bag> </class> <class name='Column' table='ARR_LOOKUP_COLUMN'> <id name='id' column='ID'> <generator class='native'/> </id> <!-- Some properties here --> </class>
In my Spring config file I have:
<tx:advice id='txAdvice' transaction-manager='txManager'> <tx:attributes> <tx:method name='*' propagation='REQUIRED'/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id='managers' expression='execution(public * com.foo.*Manager.*(..))'/> <aop:advisor advice-ref='txAdvice' pointcut-ref='managers'/> </aop:config>
And finally the code where it all fails within my manager class (com.foo.LookupTableManager):
public void addColumnToTable(Column column, long tableId) { LookupTable lookupTable = this.lookupTableDao.findById(tableId); lookupTable.addColumn(column); this.lookupTableDao.saveOrUpdate(lookupTable); }
The variable lookupTableDao here refers to a simple DAO class which extends HibernateDaoSupport.
The error I get is:
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410) at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:43) at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101) at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61) at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55) at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507) at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499) at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495) at com.foo.AbstractDao.saveOrUpdate(AbstractDao.java:29) at com.foo.LookupTableManager.addColumnToTable(LookupTableManager.java:338) ... etc ...
OK, I understand the basic message I’m getting. But what I don’t understand is where I get the second session…. Can anyone help me with this?
I’m using Hibernate 3.2.6.ga, Spring 2.5.5 and Tomcat 6.0
Turns out I didn’t have a transaction at all. I used almost the same transaction configuration in one of my other config files.
The pointcut over there was also called ‘managers’, so my advisor here was referencing the pointcut in the other file.
Renaming the pointcut solved my problem.