#hibernate #transactions #quarkus-panache #orphan-removal
Вопрос:
У меня странное поведение с гибернацией. Мое окружение-Кваркус с щегольством, но я думаю, что на самом деле это не связано с проблемой.
Я использую простую древовидную сущность с идентификатором родителя и потомков. Мой метод перемещения только что переместил ребенка в другого родителя:
- Я забрал ребенка у старого родителя
- Я добавил ребенка в нового родителя
После транзакции дочерний элемент полностью удаляется, и действие добавления не учитывается.
Это нормальное поведение?
Сущность :
@Entity(name = "Element")
@Access(AccessType.PROPERTY)
@Inheritance(strategy = InheritanceType.JOINED)
public class Element {
private Long id;
private Element parent;
private List<Element> subActivities = new ArrayList<>();
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////// Getteur Setteur /////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@JsonManagedReference
@OneToMany(mappedBy = "parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
public List<Element> getSubActivities() {
return this.subActivities;
}
public void setSubActivities(List<Element> sousactivites) {
this.subActivities = sousactivites;
}
@JsonBackReference
@ManyToOne()
@JoinColumn(name = "parent", referencedColumnName = "id")
public Element getParent() {
return this.parent;
}
public void setParent(Element parent) {
this.parent = parent;
}
Моя служба :
@ApplicationScoped
public class ElementService {
@Inject
ElementRepository repository;
public static Long id1;
public static Long id2;
public static Long id3;
/** Prepare the test */
@Transactional
public void create() {
Element element1 = new Element();
Element element2 = new Element();
Element element3 = new Element();
this.add(element1, element3);
repository.persist(element1);
repository.persist(element2);
repository.persist(element3);
id1 = element1.getId();
id2 = element2.getId();
id3 = element3.getId();
}
/** Test method */
public void test() {
Element element1 = repository.findById(id1);
Element element2 = repository.findById(id2);
Element element3 = repository.findById(id3);
System.out.println("________________ before _____________");
System.out.println(element1 " " element1.getSubActivities());
System.out.println(element2 " " element2.getSubActivities());
moveInto(element2.getId(), element3.getId());
Element element01 = repository.findById(id1);
Element element02 = repository.findById(id2);
Element element03 = repository.findById(id3);
System.out.println("________________ after _____________");
System.out.println(element01 " " element01.getSubActivities());
System.out.println(element02 " " element02.getSubActivities());
}
/** Problematic method */
@Transactional
public void moveInto(Long parentId, Long nodeId) {
Element parent = repository.findById(parentId);
Element node = repository.findById(nodeId);
moveInto(parent, node);
}
void moveInto(Element parent, Element tnode) {
this.remove(tnode);
this.add(parent, tnode);
}
void remove(Element node) {
if (node.getParent() != null) {
boolean deleted = node.getParent().getSubActivities().remove(node);
node.setParent(null);
System.out.println("isDeleted ? : " deleted);
}
}
void add(Element parent, Element value) {
if (parent.getSubActivities() != null) {
boolean added = parent.getSubActivities().add(value);
value.setParent(parent);
System.out.println("isAdded ? : " added);
}
}
}
Результат :
________________ before _____________
fr.projetlineaire.ganttonline.activity.test.Element@5213dcac [fr.projetlineaire.ganttonline.activity.test.Element@34699167]
fr.projetlineaire.ganttonline.activity.test.Element@44cbb4c2 []
isDeleted ? : true
isAdded ? : true
________________ after _____________
fr.projetlineaire.ganttonline.activity.test.Element@5213dcac []
fr.projetlineaire.ganttonline.activity.test.Element@44cbb4c2 []
Ответ №1:
Это может быть ошибка в режиме гибернации, для которой вам следует отправить уведомление об ошибке в службу отслеживания проблем(https://hibernate.atlassian.net) с вашим тестом case(https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-5/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java), который воспроизводит проблему.
Однако я на самом деле считаю, что удаление сирот просто не работает так, как вы ожидали бы в данном конкретном случае. Проблема может заключаться в том , что вы используете mappedBy
, но было бы лучше просто отправить проблему и подождать анализа вопроса командой Hibernate.