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.delete(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.