Здравствуйте, имеются два POJO-класса.
public class PatienceEntity {
private int id;
private String fio;
private Set disease;
private Set analysis; //элементы сета типа AnalysisEntity
}
public class AnalysisEntity {
private int id;
private TypeOfAnalysisEntity typeOfAnalys;
private PatienceEntity patience;
}
Как видно из кода, у каждого класса есть ссылка на другой класс. Dao для этих классов выглядит вот так.
CrudDao - общий родитель для классов
public abstract class CrudDao <ID, T> {
protected SessionFactory sessionFactory;
void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public CrudDao(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void create(T o) {
Session session;
try {
session = sessionFactory.getCurrentSession();
} catch (HibernateException ex) {
session = sessionFactory.openSession();
}
Transaction transaction = null;
transaction = session.beginTransaction();
session.save(o);
transaction.commit();
}
public T read(ID id, Class classToRead) {
Session session;
try {
session = sessionFactory.getCurrentSession();
} catch (HibernateException ex) {
session = sessionFactory.openSession();
}
Transaction transaction = null;
transaction = session.beginTransaction();
T occupiedBedsEntity = (T) session.load(classToRead, Integer.parseInt(id.toString()));
transaction.commit();
return occupiedBedsEntity;
}
public void update(T o) {
Session session;
try {
session = sessionFactory.getCurrentSession();
} catch (HibernateException ex) {
session = sessionFactory.openSession();
}
Transaction transaction = null;
transaction = session.beginTransaction();
session.update(o);
transaction.commit();
}
public abstract void delete(ID id);
public abstract List list();
}
AnalysisDao
public class AnalysisDao extends CrudDao<Integer, AnalysisEntity>{
public AnalysisDao( SessionFactory sessionFactory){
super(sessionFactory);
}
public void delete(Integer id) {
Session session;
try {
session = sessionFactory.getCurrentSession();
} catch (HibernateException ex) {
session = sessionFactory.openSession();
}
Transaction transaction = null;
transaction= session.beginTransaction();
SQLQuery query = session.createSQLQuery("DELETE FROM analysis WHERE id = :analys_id");
query.addEntity(AnalysisEntity.class);
query.setParameter("analys_id",id);
query.executeUpdate();
transaction.commit();
}
public List list(){
Session session;
try {
session = sessionFactory.getCurrentSession();
} catch (HibernateException ex) {
session = sessionFactory.openSession();
}
Transaction transaction = null;
transaction= session.beginTransaction();
List staffEntity = session.createQuery("FROM AnalysisEntity").list();
transaction.commit();
return staffEntity;
}
}
PatienceDao(почти тоже, что и AnalysisDao)
Mapping xml файлы выглядят вот так:
AnalysisEntity.hbm.xml
<hibernate-mapping default-cascade="all" default-lazy="false">
<class name="entity.AnalysisEntity" table="analysis" schema="" catalog="medicine">
<id name="id">
<column name="id" sql-type="int unsigned" not-null="true"/>
<generator class="native"/>
</id>
<many-to-one name="typeOfAnalys" column="id_type_of_analysis" class="entity.TypeOfAnalysisEntity" />
<many-to-one name="patience" column="id_patience" class="entity.PatienceEntity"/>
</class>
</hibernate-mapping>
PatienceEntity.hbm.xml
<hibernate-mapping default-cascade="all" default-lazy="false">
<class name="entity.PatienceEntity" table="patience" schema="" catalog="medicine">
<id name="id">
<column name="id" sql-type="int unsigned" not-null="true"/>
</id>
<property name="fio">
<column name="FIO" sql-type="varchar" length="100" not-null="true"/>
</property>
<set name="analysis">
<key column="id_patience"></key>
<one-to-many class="entity.AnalysisEntity"/>
</set>
<set name="disease" table="patiente_in_hospital">
<key column="id_patience"></key>
<many-to-many column="id_disease" class="entity.DiseaseEntity"/>
</set>
</class>
</hibernate-mapping>
Ошибка вылазит на этих строках
AnalysisEntity analysisEntity = AnalysisEntity.class.cast(entity);
TypeOfAnalysisDao typeOfAnalysisDao = new TypeOfAnalysisDao(Main.getOurSessionFactory());
TypeOfAnalysisEntity typeOfAnalysisEntity = typeOfAnalysisDao.read(Integer.parseInt(firstField.getText()), TypeOfAnalysisEntity.class);
analysisEntity.setTypeOfAnalys(typeOfAnalysisEntity);
PatienceDao patienceDao =new PatienceDao(Main.getOurSessionFactory());
analysisEntity.setPatience(patienceDao.read(Integer.valueOf(lastField.getText()), PatienceEntity.class));
Стек ошибки
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException:
Caused by: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions. Collection : [entity.PatienceEntity.analysis#1]
at org.hibernate.collection.internal.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:623)
at org.hibernate.event.internal.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:46)
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
at org.hibernate.event.internal.AbstractVisitor.process(AbstractVisitor.java:126)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:293)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:227)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:92)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:647)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:639)
at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:218)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:379)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:304)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:146)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:95)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:425)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:249)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:178)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:109)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:678)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:670)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:665)
at dao.CrudDao.create(CrudDao.java:36)
at FX.StaffController.handleNewStaff(StaffController.java:204)
... 62 more
Собственно вопрос: где открывается вторая сессия? Может ли это быть из перекрёстных ссылок классов друг на друга?