I am developing a file management application under JSF/Primefaces and Tomee/OpenJPA. I am having a weird bug that is getting me crazy !
So here is my Entity :
@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 ..
}
It represent files and directories (depending on fileType
). A directory could have children.
I am creating the database from my entities. To retrieve all the directories of the database I use this code:
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();
}
My problem is that whenever I exceed 1 child of a directory I get this error:
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
And the error is at line return typedQuery.getResultList();
Persist and merge work just fine (I can persist a child of child, in the database it looks good, but with the criteriaQuery i get the error)
Does anyone see where could the problem come from ? Thanks (I am literally getting crazy ! I did my best to write the question correctly indented, sorry if not looking good)
At last I found the answer !!
In fact, the collections annotated @OneToMany
and @ManyToOne
cause the framework to go into an infinite loop when trying to fetch a MyBoxFile
with its parent and children (when fetching the parent it will try to fetch its children and then for each child try to fetch its children and its prents ... infinitely !).
The most unexpected solution is to add the transient
keyword for each one of these collections (it was only luck which got me to try it).
I hope it will help someone in the future.