Hibernate,从集合中删除

时间:2016-02-05 14:27:38

标签: java hibernate collections

我有一个包含2个表的数据库,这些表按一对多关系连接。我通过Hibernate来访问该数据库。

这是hbm.xml文件:

question.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="app">  
  <class name="Question" table="Question">
        <id name="id" column="id" type="java.lang.Long">
            <generator class="native"/>
        </id>
        <property name="text" column="text" type="java.lang.String" not-null="true"/>                

        <set name="answers" cascade="all">
            <key column="question_id"/>
            <one-to-many class="Answer"/>
        </set>           
    </class>
</hibernate-mapping>

answer.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="app">    
  <class name="Answer" table="Answer">
        <id name="id" column="id" type="java.lang.Long">
            <generator class="native"/>
        </id>
        <property name="text" column="text" type="java.lang.String" not-null="true"/>        
        <many-to-one name="question" column="question_id" class="Question" not-null="true"/>
    </class>
</hibernate-mapping>

这是java文件:

Question.java

package app;


import java.util.Set;


public class Question {
    Long id = null;
    String text = "";
    Set<Answer> answers = null;

    // getters and setters
}

Answer.java

package app;


public class Answer {
    Long id = null;    
    String text = "";
    boolean isTrue = false;
    Question question = null;

    // getters and setters
}

所以问题可以有答案,问题实例有一个答案实例的集合。

这是主要方法

package application;


import app.Answer;
import app.Question;
import java.util.HashSet;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


public class Application {

    public static void main(String[] args) {

        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
        Session session = sessionFactory.openSession();      

        Question question = new Question();        
        question.setText("question1");

        Answer answer1 = new Answer();        
        answer1.setText("answer1");
        answer1.setQuestion(question);
        Answer answer2 = new Answer();        
        answer2.setText("answer2");
        answer2.setQuestion(question);

        HashSet<Answer> answers = new  HashSet<>();
        answers.add(answer1);
        answers.add(answer2);        
        question.setAnswers(answers);

        session.beginTransaction();        
        try {            
            session.saveOrUpdate(question);   
            session.getTransaction().commit();
        } catch (Exception ex) {
            ex.printStackTrace();
            session.getTransaction().rollback();
        }

        answers.remove(answer2);

        session.beginTransaction();        
        try {            
            session.saveOrUpdate(question);   
            session.getTransaction().commit();
        } catch (Exception ex) {
            ex.printStackTrace();
            session.getTransaction().rollback();
        }
    }
}

所以我创建了Question实例,在Question实例中将两个Answers实例添加到集合中,并将Question实例保存在数据库中。一切正常 - 问题和答案写入数据库。 然后我从Question实例中的集合中重新构建一个Answers实例,并尝试再次将Question实例保存在数据库中。我抓到了一个例外。它是我的母语,但它是SQLServerException,它说的是这样的:“不能在表”Test.dbo.Answer“中的列”question_id“中插入NULL,在此列中禁止NULL。更新错误”< / p>

怎么了?如何删除问题答案中的一个?

2 个答案:

答案 0 :(得分:0)

saveOrUpdate()仅用于创建新记录(如果不存在)或更新(如果存在)。请在下面找到伪代码。

Question question = new Question(); 
question.setText("question1");

Answer deleteAns=new Answer();
deleteAns.setText("answer2");

question.setAnswer(deleteAns);
session.dele‌​te(question) 

答案 1 :(得分:0)

在双向关系中,一方必须是反向关系。在one-to-many关联中,通常是one-方:

<set name="answers" cascade="all" inverse="true">
  <key column="question_id"/>
  <one-to-many class="Answer"/>
</set>

这样只有many-方才会处理这种关系。

在您的情况下,双方都这样做,并且由于外键位于Answer类/表中,因此在清除null中的关联更改时,Hibernate会将其更新为Question类。