0

我对 Hibernate 有一个奇怪的行为。我的环境是带有 Panache 的 Quarkus,但我认为它与问题无关。

我正在使用一个带有 id、父级和子级的简单树实体。我的 moveInto 方法只是将一个孩子移动到另一个父母:

  • 我把孩子从老父母身上移走了
  • 我在新的父母中添加了孩子

事务完成后,孩子被完全移除,并且不考虑添加的动作。

这是正常行为吗?

实体 :

@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 []
4

1 回答 1

0

这可能是一个 Hibernate 错误,您应该使用您的测试用例(https://github.com/hibernate/hibernate-test-case-)在问题跟踪器(https://hibernate.atlassian.net)提交错误票证。重现问题的模板/blob/master/orm/hibernate-orm-5/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java)。

不过,我实际上相信,在这种特殊情况下,孤儿删除并不像您期望的那样起作用。问题可能是你在使用mappedBy,但最好只是提交问题并等待 Hibernate 团队对此事进行分析。

于 2021-10-14T05:22:18.427 回答