我正在开发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我得到了错误)
有谁看到问题可能来自哪里? 谢谢(我真的疯了!我尽力把问题写成正确的缩进,抱歉,如果不好看的话)
答案 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
关键字(只有运气才能让我尝试它)。
我希望将来可以帮助某人。