我有以下對象:春天 - 休眠:通過堅持脫離實體
public class Constraint {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
int id;
String name;
String description;
String path;
int level;
@ManyToOne
@JoinColumn(name="parent_id")
Constraint parent;
@OneToMany
@JoinColumn(name="parent_id")
Set<Constraint> children;
@ManyToOne
@JoinColumn(name="type_id")
ConstraintType type; }
正如你看到這個表是一個樹狀結構。具有功能:
public List<Constraint> getAllDescendantsOfConstraint(Integer id) {
StringBuilder sb = new StringBuilder();
sb.append("WITH RECURSIVE tree as ");
sb.append("(");
sb.append(" select * from constraints where id = :id ");
sb.append(" union all ");
sb.append(" select a.* from constraints a, tree b where a.parent_id = b.id ");
sb.append(") ");
sb.append("select * from tree where id <> :id ");
Query q = entityManager.createNativeQuery(sb.toString(), Constraint.class);
q.setParameter("id", id);
return (List<Constraint>) q.getResultList();
}
@Transactional
public void setupPaths() {
Query q = entityManager.createQuery("from Constraint", Constraint.class);
@SuppressWarnings("unchecked")
List<Constraint> constraints = (List<Constraint>) q.getResultList();
for(Constraint c : constraints) {
List<Constraint> descendants = getAllDescendantsOfConstraint(c.getId());
for(Constraint d : descendants) {
String tpath;
if((tpath = d.getPath()) == null || d.getPath().equals(""))
tpath = String.valueOf(c.getId());
else
tpath = d.getPath() + "." + String.valueOf(c.getId());
d.setPath(tpath);
entityManager.persist(d);
}
}
}
如果呼叫setupPaths我得到一個「傳遞給持續異常超脫實體」。 如果代替entityManager.persist(d);
我做的:
d = entityManager.merge(d);
d.setPath(tpath);
什麼也沒有發生(數據未保存在數據庫)。如果一個調用刷新,我得到分離的實體傳遞給持久異常。我懷疑這和我有關,不是急於加載父母或孩子?因爲上面看起來真的很可疑,看起來我從entityManager得到的每一個實體,無論我如何得到它(無論是用em.find(MyObject.class,id還是任何種類的查詢)它被取後分離吧!我看到,從調用
em.contains(myObject)
它總是返回false。問題是,我用其他的Spring項目完全相同的設置使用相同的數據庫服務器,它的wroking罰款。