简体   繁体   中英

Hibernate, delete from collection

I have a database that contain 2 tables that connect by one-to-many relationship. I enteract with that database through Hibernate.

This is hbm.xml files:

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>

And this is java files:

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
}

So Question can have Answers and Question instance has a collection fo Answers instances.

This is main method :

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();
        }
    }
}

So I create Question instance, add two Answers instances to collection in Question instance and save Question instance in database. All work correctly - Question and Answers is writen to database. Then I remome one of Answers instance from collection in Question instance and try to save Question instance in database again. I catch an Exception. It's in my native language, but it is SQLServerException and it say something like this: "Can't insert NULL in column "question_id" in table "Test.dbo.Answer", in this column NULL is forbidden. Error in UPDATE"

What's wrong? How can I delete one of Answer from Question?

saveOrUpdate() is only for createing a new record if doesnt exist or updating if it does exist.Please find the pseudocode below.

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

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

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

In a bidirectional relationship one side has to be the inverse one. In a one-to-many association that is usually the one- side:

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

This way only many- side will take care of the relationship.

In your case, both sides do it, and since the foreign key is in the Answer class/table, Hibernate updates it to null when flushing the association changes in the Question class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM