Я пытаюсь отобразить несколько таблиц, которые имеют ManyToMany
ассоциации, но я получил ошибку, которая, вероятно, появляется из-за сложного отображения:
Class Student:
@Entity
@Table(name = "student")
@PrimaryKeyJoinColumn(name = "user_id")
@OnDelete(action = OnDeleteAction.CASCADE)
public class Student extends User {
private int grade;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name = "student_assessment",
joinColumns = { @JoinColumn(name = "student_id") },
inverseJoinColumns = { @JoinColumn(name = "assessment_id") }
)
Set<Assessment> assessments = new HashSet<Assessment>();
//getters & setters
ClassОценки:
@Entity
@Table(name = "assessment")
@Access(AccessType.FIELD)
public class Assessment {
@Id
private int id;
private String name;
@Column(name = "chapter_id")
private int chapterId;
private int grade;
private String type;
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name = "assessment_question",
joinColumns = { @JoinColumn(name = "assessment_id") },
inverseJoinColumns = { @JoinColumn(name = "question_id") }
)
Set<Question> questions = new HashSet<Question>();
@ManyToMany(mappedBy = "assessments")
public Set<Student> students = new HashSet<Student>();
//getters & setters
Вопрос о классе:
@Entity
@Table(name = "question")
public class Question {
@Id
private int id;
@Column(name = "question_text")
private String text;
@Column(name = "chapter_id")
private int chapterId;
@ManyToMany(mappedBy = "questions")
public Set<Assessment> assessments = new HashSet<Assessment>();
//getters & setters
Сущность Student
имеет отношение ManyToMany
с сущностью Assessment
, поэтому в моей базе данных есть таблица student_assessment
.
Но также, у сущности Assessment
есть ManyToMany
с сущностью Question
, следовательно, в базе данных есть таблица assessment_question
.
Сейчас я пытаюсь сделать следующее:сохранить новую запись в таблице student_assessment
, используя hibernate, как показано ниже, в моем классе DAO:
private Session currentSession;
private Transaction currentTransaction;
public StudentAssessmentDAO() {
}
public Session openCurrentSession() {
currentSession = getSessionFactory().openSession();
return currentSession;
}
public Session openCurrentSessionwithTransaction() {
currentSession = getSessionFactory().openSession();
currentTransaction = currentSession.beginTransaction();
return currentSession;
}
public void closeCurrentSession() {
currentSession.close();
}
public void closeCurrentSessionwithTransaction() {
currentTransaction.commit();
currentSession.close();
}
private static SessionFactory getSessionFactory() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml").addAnnotatedClass(Student.class).addAnnotatedClass(Assessment.class).addAnnotatedClass(Question.class);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());
return sessionFactory;
}
public void persist(Student student, Assessment assessment) {
student.getAssessments().add(assessment);
getCurrentSession().save(student);
}
В моем основном классе я просто выполняю:
dao.openCurrentSessionwithTransaction();
dao.persist(student, assessment);
dao.closeCurrentSessionwithTransaction();
Thisэто ошибка, которую я получаю:
Exception in thread "main" org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions. Collection : [models.Student.assessments#1]
at org.hibernate.collection.internal.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:646)
at org.hibernate.event.internal.WrapVisitor.processCollection(WrapVisitor.java:49)
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
at org.hibernate.event.internal.WrapVisitor.processValue(WrapVisitor.java:108)
at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
at org.hibernate.event.internal.AbstractSaveEventListener.visitCollectionsBeforeSave(AbstractSaveEventListener.java:395)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:277)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:200)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:131)
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:709)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:701)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:696)
at dao.StudentAssessmentDAO.persist(StudentAssessmentDAO.java:71)
at webapp.Main.main(Main.java:184)
Я предполагаю, что ошибка происходит из-за того, что подключено несколько сущностей, и, следовательно, как-то открыто больше сеансов, но я не могу найти способреши это.Когда я использовал только сопоставление между оценкой и вопросом, мне удается сохранить и прочитать из базы данных, но когда я добавил сопоставление ученика, оно больше не работает.Есть идеи, как мне решить эту проблему?