【问题标题】:Hibernate, delete from collection休眠,从集合中删除
【发布时间】:2016-02-05 14:27:38
【问题描述】:

我有一个数据库,其中包含 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
}

所以 Question 可以有 Answers 并且 Question 实例有一个 Answers 实例的集合。

这是主要方法

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 实例,将两个 Answers 实例添加到 Question 实例的集合中,并将 Question 实例保存在数据库中。一切正常 - 问题和答案被写入数据库。 然后我从 Question 实例的集合中删除一个 Answers 实例,并尝试再次将 Question 实例保存在数据库中。我发现了一个异常。它是我的母语,但它是 SQLServerException,它说的是这样的:“无法在表“Test.dbo.Answer”中的“question_id”列中插入 NULL,在此列中禁止 NULL。UPDATE 中的错误“

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

【问题讨论】:

  • 我认为你应该通过你的会话对给定的对象调用 delete:session.delete(entity);
  • saveOrUpdate() 仅用于在不存在时创建新记录或在存在时更新。请在下面找到伪代码。问题问题 = 新问题(); question.setText("question1");Answer deleteAns=new Answer();deleteAns.setText("answer2");question.setAnswer(deleteAns);session.delete(question)

标签: java hibernate collections


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

    Question question = new Question(); 
    question.setText("question1");
    
    Answer deleteAns=new Answer();
    deleteAns.setText("answer2");
    
    question.setAnswer(deleteAns);
    session.dele‌​te(question) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-21
      • 2013-09-28
      • 2016-07-11
      • 1970-01-01
      • 2011-03-26
      • 2011-06-14
      相关资源
      最近更新 更多