Hibernate如何在@OneToMany中正确删除子项?

时间:2014-10-23 15:59:21

标签: java hibernate hibernate-onetomany

我有一个非常简单的单向@OneToMany,从Parent对象到具有CascadeType.ALL的子列表。我如何正确删除和删除其中一个孩子?

只需在List上调用remove(child),然后session.saveOrUpdate(parent)当然不起作用,除非我指定删除orphan,否则不会删除数据库中的子项。

作为孤儿删除的替代方法,如果我将session.delete(child)删除到DB中,然后从List中删除(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 个答案:

答案 0 :(得分:2)

当您想要手动执行@Cascade(DELETE_ORPHAN)(来自Hibernate)时,这里的代码执行的行为几乎相同。

实体:

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

您的图书将从数据库中删除,同时父母也会更新。

答案 1 :(得分: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();
    }
}