插入多个子项时,JPA中的父子关系出错

时间:2014-03-07 17:37:06

标签: java-ee jpa primefaces openjpa tomee

我正在开发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: <openjpa-2.3.0-nonfinal-1540826-r422266:1542644 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: null

错误在第return typedQuery.getResultList();

坚持并合并工作就好了(我可以坚持孩子的孩子,在数据库中它看起来不错,但是使用criteriaQuery我得到了错误)

有谁看到问题可能来自哪里? 谢谢(我真的疯了!我尽力把问题写成正确的缩进,抱歉,如果不好看的话)

2 个答案:

答案 0 :(得分:0)

假设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");

我希望它有所帮助。

答案 1 :(得分:0)

最后我找到了答案!! 事实上,注释@OneToMany@ManyToOne的集合会导致框架在尝试使用其父项和子项获取MyBoxFile时进入无限循环(当获取父项时,它将尝试取出它的孩子,然后为每个孩子尝试获取它的孩子及其蚂蚁......无限!)。 最意想不到的解决方案是为这些集合中的每一个添加transient关键字(只有运气才能让我尝试它)。 我希望将来可以帮助某人。