Hibernate:坚持树状结构

时间:2014-06-11 06:36:54

标签: java hibernate

我在Collection中有一个树状结构。我确保集合中的所有节点都不会产生无关的引用,并进行拓扑排序,使得集合头部的根节点和所有叶子都接近它的末尾。

我的主要抽象节点类是这样的:

@Entity
public abstract class Node {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long ID;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "parent_id", insertable = false, updatable = false)
    Node parent;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "root_id", insertable = false, updatable = false)
    Node root;
}

我没有维护子列表,但每个节点都指向其父节点。 root引用是一个便捷字段,用于引用树的根节点。例如,删除整个树将更容易。现在我有许多来自Node的后代,例如AB C等。

问题:

当尝试保留整个树时,我使用以下代码。

    // Check for extraneous references, and sort them topologically.
    Session s = hibernate.openSession();
    Transaction tx = s.beginTransaction();
    try {
        int i = 0;
        for (Node p: objects) {
            if (p.parent == null) {
                throw new IOException("Parent is `null`.");
            }
            s.persist(p);
            if (i % batchSize == 0) {
                s.flush();
                s.clear();
            }
            i++;
        }
        tx.commit();
    }
    catch (Throwable t) {
        log.error(t.getMessage(), t);
        tx.rollback();
        throw new IOException(t);
    }

此方法无法正确保留对象。如果批量太小,我会得到一条PersistentObjectException,上面有一条消息:

org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.Node

如果批量大小至少与我可以保留的对象总数一样大,但数据库中的PARENT_IDROOT_ID都设置为null。我在测试时使用H2。请注意,类A始终是根节点,所有其他对象可以显示在A以下的任何级别。我也试过了s.merge(),但那也没有用。我已根据我的业务密钥实施了equals()hashCode()

我的equals / hashCode方法有问题吗?或者这是我试图坚持的方式?我不知道我的代码有什么问题。不知何故,我觉得这是一个微不足道的错误,我忽略了基本方面。有人可以帮我解决一下吗?我尝试通过不同的博客阅读,讨论使用Hibernate进行分层表示,但没有任何帮助。

1 个答案:

答案 0 :(得分:0)

尝试删除s.clear()

它基本上是从持久化上下文中分离对象,这可能导致异常detached entity passed to persist