2016-02-05 2 views
1

У меня есть база данных, которая содержит 2 таблицы, которые соединяются отношениями «один ко многим». Я вступаю в эту базу данных через Hibernate.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> 

И это ява файлы:

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 
} 

Так Вопрос может иметь ответы и экземпляр Вопрос имеет коллекцию Fo Ответы экземпляров.

Это основной метод:

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

Так я создаю экземпляр вопрос, добавить два ответы экземпляров в коллекции в случае вопрос и сохранить экземпляр вопрос в базе данных. Все работает правильно - вопрос и ответы записываются в базу данных. Затем я возвращаю один экземпляр ответов из коллекции в экземпляре вопроса и снова пытаюсь сохранить экземпляр объекта в базе данных. Я поймаю Исключение. Это на моем родном языке, но это SQLServerException, и он говорит примерно так: «Невозможно вставить NULL в столбец« question_id »в таблицу« Test.dbo.Answer », в этом столбце запрещается NULL. Ошибка в UPDATE«

Что случилось? Как удалить один из ответов «Ответ»?

+0

Я думаю, вам нужно просто вызвать delete на данном объекте через сеанс: session.delete (entity); –

+0

saveOrUpdate() предназначен только для создания новой записи, если она не существует или не обновляется, если она существует. Пожалуйста, найдите псевдокод ниже. Вопрос question = new Question(); question.setText ("question1"); Answer deleteAns = new Answer(); deleteAns.setText ("answer2"); question.setAnswer (deleteAns); session.delete (question) – Shaan

ответ

0

В двунаправленной связи одна сторона должна быть обратной. В one-to-many ассоциации, которая обычно является one- стороны:

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

Таким образом, только many- стороны будет заботиться о взаимоотношениях.

В вашем случае, обе стороны сделать это, и так как внешний ключ в Answer класса/таблицы, Hibernate обновления его null при промывке изменений ассоциации в Question классе.

0

saveOrUpdate() предназначен только для создания новой записи, если она не существует или не обновляется, если она существует. Пожалуйста, найдите псевдокод ниже.

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

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

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