我在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的后代,例如A
,B
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_ID
和ROOT_ID
都设置为null
。我在测试时使用H2。请注意,类A
始终是根节点,所有其他对象可以显示在A
以下的任何级别。我也试过了s.merge()
,但那也没有用。我已根据我的业务密钥实施了equals()
和hashCode()
。
我的equals / hashCode方法有问题吗?或者这是我试图坚持的方式?我不知道我的代码有什么问题。不知何故,我觉得这是一个微不足道的错误,我忽略了基本方面。有人可以帮我解决一下吗?我尝试通过不同的博客阅读,讨论使用Hibernate进行分层表示,但没有任何帮助。
答案 0 :(得分:0)
尝试删除s.clear()
。
它基本上是从持久化上下文中分离对象,这可能导致异常detached entity passed to persist