2014-10-23 5 views
0

У меня очень простой однонаправленный @OneToMany из родительского объекта в список детей с CascadeType.ALL. Как правильно удалить и удалить одного из детей?Hibernate Как правильно удалить детей в @OneToMany?

Просто позвоните remove (child) в List, а затем session.saveOrUpdate (родительский), конечно, не работает, и ребенок не будет удален в базе данных, если я не укажу удаление сирот.

В качестве альтернативы удалению сирот было бы правильным, если бы я session.delete (child) удалял его в БД, а затем удалял (дочерний) из списка и выполнял ли я затем session.refresh (parent) поэтому мой родительский объект в памяти имеет правильное состояние?

Как правильно удалить ребенка и удалить его в базе данных без удаления сирот?

В настоящее время я думал об этом в моем ParentDao:

public void removeChild(Parent parent, Child child) { 
    Session session = HibernateUtil.getSessionFactory().openSession(); 
    Transaction tx = null; 
    try { 
     session.beginTransaction(); 

     session.delete(child); 

     session.getTransaction().commit(); 

     parent.getChildren().remove(child); 
     session.refresh(parent); 
    } catch (RuntimeException e) { 
     if (tx != null) { 
      tx.rollback(); 
     } 
     throw e; 
    } finally { 
     session.close(); 
    } 
} 

ответ

2

Как область собирается сделать @Cascade (DELETE_ORPHAN) (из спящего режима) вручную, вот код, который делает почти то же самое поведение ,

Сущность:

class Library { 

    @Id 
    private Integer id; 

    @OneToMany 
    private List<Book> books; 

    // getters and setters  
} 

class Book { 

    @Id 
    private Integer id; 

    @ManyToOne 
    private Libraby library; 

    // getters and setters 
} 

И простой пример:

session.beginTransaction(); 

// load a library with ID = 1 
Library library = session.get(Library.class, 1); 

// assuming that your library has two books 
Book book = library.getBooks().get(0); //gets the first book 
library.getBooks().remove(0); // Remove this book from the library 
session.delete(book); 

session.getTransaction().commit(); 

И ваша книга будет удалена из базы данных и lisf флористики родитель будет обновляться, а также.

+0

На самом деле, мой главный вопрос: как мне это сделать вручную, без DELETE_ORPHAN? – karrjin

+0

Извините, но почему вы сделали это вручную? – leozin

+0

Я пытаюсь понять это лучше. – karrjin

0

Вы можете попробовать под кодом? Удаление из списка перед фиксацией.

public void removeChild(Parent parent, Child child) { 
    Session session = HibernateUtil.getSessionFactory().openSession(); 
    Transaction tx = null; 
    try { 
     session.beginTransaction(); 

     parent.getChildren().remove(child); 
     session.delete(child); 

     session.getTransaction().commit(); 


     // session.refresh(parent); // this is not required 
    } catch (RuntimeException e) { 
     if (tx != null) { 
      tx.rollback(); 
     } 
     throw e; 
    } finally { 
     session.close(); 
    } 
} 
+0

Спасибо! Но если я не обновляю (родительский), то добавляю нового ребенка и снова вызываю saveOrUpdate (родительский) снова, я получаю org.hibernate.StaleStateException: пакетное обновление возвращало неожиданный счетчик строк из обновления [0]; фактическое количество строк: 0; Ожидаемый: 1 Так что я думаю, что мне нужно сначала вызвать refresh(). Удаление удалённого объекта из коллекции недостаточно. – karrjin

+0

Итак, после обновления он работает? – javafan