У меня есть следующий объект:
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);
Ничего не происходит (данные не сохраняются в БД).Если вызов сброшен, я получаю отдельную сущность, переданную для сохранения исключения.Я подозреваю, что это как-то связано с тем, что я не загружаю родителей или детей?
edit: После дальнейшего тестирования, поскольку вышеприведенное кажется действительно подозрительным, кажется, что каждая сущность, которую я получаю от entityManager, независимо от того, как я получаюон (либо с em.find (MyObject.class, id, либо с любым видом запросов) отключается сразу после извлечения! Я вижу, что от вызова
em.contains(myObject)
, который всегда возвращает false. Проблема в том, что яиспользуйте ту же самую настройку в других проектах Spring с тем же сервером базы данных, и все работает нормально.