I'm building a web app with Stripes/Spring/Hibernate. Basic CRUD-type app. On one page, there's a list of volumes loaded with code from the class VolumesActionBean, and the user can click on one to edit it, which will then open an edit page where the individual volume is again requested by code in VolumeTypeConverter (it's a Stripes idiom). On save, the volume is requested again from VolumeTypeConverter then saved by code in VolumeActionBean.
The problem is that once the change is made, any attempt to save results in
Code:
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
I've extracted the problem down into a unit test that throws the exception:
Code:
package com.dahosek.catalog.book.dao;
import java.util.List;
import org.junit.*;
import com.dahosek.catalog.book.Volume;
import org.hibernate.*;
import org.hibernate.cfg.*;
public class VolumeHibernateDaoTest {
@Test
public void canLoadAndSave() {
VolumeHibernateDao dao = new VolumeHibernateDao();
SessionFactory sessionFactory = new AnnotationConfiguration()
.configure()
.buildSessionFactory();
dao.setSessionFactory(sessionFactory);
List<Volume> volumes = dao.findAll();
Long id = volumes.get(0).getId();
Volume volume = dao.findById(id, true); //(3)
volume.setCallNumber("New Call Number"); //(1)
dao.makePersistent(volume); //(2)
Volume vol2 = dao.findById(id, false);
Assert.assertEquals("New Call Number", vol2.getCallNumber());
}
}
Removing the line at (1) removes the exception thrown at (2). The question is, given the structure of the application, I can't avoid the request to generate a new object at (3). How do I get the application to work without the exception being thrown?
(My Dao class is a slightly modified version of the Dao class from the Bauer/King book).