【问题标题】:Parent-child relationship in JPA error when inserting more than one child插入多个孩子时JPA中的父子关系错误
【发布时间】:2014-03-07 17:37:05
【问题描述】:

我正在 JSF/Primefaces 和 Tomee/OpenJPA 下开发一个文件管理应用程序。 我遇到了一个让我抓狂的奇怪错误!

这是我的实体:

   @Entity
        public class MyBoxFile implements Serializable {
            private static final long serialVersionUID = 1L;    

            @Id
            @GeneratedValue(strategy=GenerationType.AUTO)
            private int id;

            private String name;

            private String fileType;   

            @Lob
            @Basic(fetch=FetchType.LAZY, optional=true)
            @Column(nullable = true, length=2000000000)
            private byte[] file;    

            @OneToOne(fetch=FetchType.EAGER)
            private MyBoxUser owner;    

            @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
            @JoinColumn(name="PARENT_ID")
            private MyBoxFile parent;    

            @OneToMany(mappedBy="parent", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
            private List<MyBoxFile> childs = new LinkedList<>();

            //Getters & Setters ..
        }

它代表文件和目录(取决于fileType)。目录可以有子目录。 我正在从我的实体创建数据库。要检索数据库的所有目录,我使用以下代码:

public List<MyBoxFile> findAllUsersDirs(MyBoxUser owner) {
    owner = em.find(MyBoxUser.class, owner.getLogin());
    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<MyBoxFile> criteriaQuery = criteriaBuilder.createQuery(MyBoxFile.class);
    Root<MyBoxFile> from = criteriaQuery.from(MyBoxFile.class);
    criteriaQuery.where(
        criteriaBuilder.and(
                       criteriaBuilder.equal(from.get(MyBoxFile_.owner), owner),

                     criteriaBuilder.equal(from.get(MyBoxFile_.fileType), "directory")
        )
    );

    TypedQuery<MyBoxFile> typedQuery = em.createQuery(criteriaQuery);
    return typedQuery.getResultList();
}

我的问题是,每当我超过一个目录的 1 个子目录时,我都会收到此错误:

The bean encountered a non-application exception; nested exception is: &lt;openjpa-2.3.0-nonfinal-1540826-r422266:1542644 nonfatal general error&gt; org.apache.openjpa.persistence.PersistenceException: null

错误在return typedQuery.getResultList();

坚持和合并工作得很好(我可以坚持一个孩子的孩子,在数据库中它看起来不错,但使用条件查询我得到错误)

有谁知道问题出在哪里? 谢谢(我真的快疯了!我尽力写出正确缩进的问题,如果看起来不好,请见谅)

【问题讨论】:

    标签: jakarta-ee jpa primefaces openjpa apache-tomee


    【解决方案1】:

    假设 JPQL 查询如下所示:

    SELECT mbf
    FROM MyBoxFile mbf
    WHERE mbf.fileType = 'directory' AND mbf.owner = :owner
    

    那么基于相关条件的查询可能如下所示:

    public static List<MyBoxFile> findAllUsersDirs(MyBoxUser owner,String fileType) {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<MyBoxFile> cq = cb.createQuery(MyBoxFile.class);
        Root<MyBoxFile> mbf = cq.from(MyBoxFile.class);
    
        cq.select(mbf);
        cq.where(cb.and(
            cb.equal(mbf.get(MyBoxFile_.owner), cb.parameter(MyBoxUser.class, "p1")),
            cb.equal(mbf.get(MyBoxFile_.fileType), cb.parameter(String.class, "p2"))
        ));
    
        TypedQuery<MyBoxFile> q = em.createQuery(cq);
        q.setParameter("p1", owner);
        q.setParameter("p2", fileType);
        return q.getResultList();
    }
    

    最后是调用:

    List<MyBoxFile> result = findAllUsersDirs(owner, "directory");
    

    希望对你有帮助。

    【讨论】:

    • 几乎...至少您没有在查询中选择任何内容;)
    • 如果我从表中选择所有内容,则条件查询中不需要...无论如何,我仍然有同样的问题
    • 我试图用 EclipseLink 重现问题,但查询就像一个魅力(有和没有选择)。您是否尝试使用最新的稳定版本(OpenJPA 2.2.3)?
    • 是的,我正在使用最新的 TomEE 发行版,它带有 OpenJPA,如果 OpenJPA 没有处理,我搜索了一下,但似乎没有任何记录...
    • 您是否尝试在没有where 语句或其参数之一的情况下执行条件查询?或者在 JavaSE(应用程序管理的实体管理器)中执行它。查询数据是否适用于 JPQL?可能无济于事,但我只是想找出根本原因。顺便提一句。我稍微更新了我的建议。
    【解决方案2】:

    终于找到答案了!! 事实上,注释 @OneToMany@ManyToOne 的集合导致框架在尝试获取 MyBoxFile 及其父级和子级时进入无限循环(当获取父级时,它会尝试获取其子级,然后每个孩子都试图获取它的孩子和它的礼物......无限!)。 最出乎意料的解决方案是为这些集合中的每一个添加transient 关键字(只是运气让我尝试了它)。 我希望它对将来的人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      • 2018-02-12
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多