我正在尝试映射具有ManyToMany
关联的多个表,但是由于复杂的映射,我可能出现了一个错误:
班级学生:
@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
课堂评估:
@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
表。
我现在要尝试的是在我的DAO类中使用休眠方式在student_assessment
表中保存新条目:
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();
这是我收到的错误:
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)
我认为错误是由于存在多个连接的实体,因此以某种方式打开了更多会话,但我找不到解决该问题的方法。当我仅使用评估和问题之间的映射时,我设法保留并从数据库中读取内容,但是当我添加学生映射时,它不再起作用。知道我该如何解决这个问题?