使用Hibernate

时间:2019-05-29 12:10:24

标签: java sql hibernate hql

我正在尝试映射具有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)

我认为错误是由于存在多个连接的实体,因此以某种方式打开了更多会话,但我找不到解决该问题的方法。当我仅使用评估和问题之间的映射时,我设法保留并从数据库中读取内容,但是当我添加学生映射时,它不再起作用。知道我该如何解决这个问题?

0 个答案:

没有答案