I came across a very weird behaviour i cant explain. When trying to read from a local DB (file on pc) the query results are only fully read back when debug printing the result contents before closing the EntityManager and Factory instance. When executing the code with the debug printing part commented out, the result doesnt contain all the data. The field requirementList is read back as null without the debug prints, although it exists in the database. With the debug prints, it is read correctly.
The class that contains the relevant field:
@Entity public class RequirementLevelEntity{ @Id @GeneratedValue private long id; private String reqLevelName = "DEF"; @OneToMany(mappedBy = "wrappingReqLevelEntity") private List requirementList; //constructors, getters and setters... }
The List that has the weird behaviour stores Objects of this type:
@Entity public class RequirementDBEntity implements Serializable { /** * */ private static final long serialVersionUID = 5019171545896480392L; @Id @GeneratedValue private long id; @ManyToOne private RequirementLevelEntity wrappingReqLevelEntity; @ManyToMany private List topReqsList; @ManyToMany private List bottomReqsList; private String name; private String description; private String reqID; private boolean verified = false; //Constructor, getters and setters, other stuff... }
The query is executed in this method:
private List read(String dbFilePath) { EntityManagerFactory emf = Persistence.createEntityManagerFactory(dbFilePath); EntityManager em = emf.createEntityManager(); TypedQuery query = em.createQuery("SELECT l from RequirementLevelEntity l", RequirementLevelEntity.class); List results = query.getResultList(); //Start of debug printing System.out.println("result size: "+results.size()); for(RequirementLevelEntity rle : results) { System.out.println("rle name "+rle.getReqLevelName()); System.out.println("rle id "+rle.getId()); List reqList = rle.getRequirementList(); //rle.getRequirementList() returns null when debug print is commented out boolean reqListIsNull = reqList==null; System.out.println("rle reqList is null: "+reqListIsNull); if(reqList != null) { System.out.println("rle reqList size "+reqList.size()); for(RequirementDBEntity reqEntity : reqList) { System.out.println("Req entity id "+reqEntity.getName()); List bottomReqList = reqEntity.getBottomReqsList(); boolean bottomIsNull = bottomReqList==null; System.out.println("Req bottom ReqList is null: "+bottomIsNull); if(bottomReqList != null) { System.out.println("BottomReqList Entities: "); for(RequirementDBEntity bottomReq : bottomReqList) { System.out.println(bottomReq.getId()); } } List topReqList = reqEntity.getTopReqsList(); boolean topIsNull = topReqList==null; System.out.println("Req top ReqList is null: "+topIsNull); if(topReqList != null) { System.out.println("TopReqList Entities: "); for(RequirementDBEntity topReq : topReqList) { System.out.println(topReq.getId()); } } } } } //End of debug print em.close(); emf.close(); return results; }
When moving the em.close() and emf.close() prior to the debug print, requirementList also returns as null, regardless of whether debug printing is commented out or not. The only way it works is: query, debug printing query results, then closing entityManager instance. Solutions i tried: Putting the thread to sleep a few seconds before closing EntityManager, running the query in a new thread. Both didnt change anything. What am i missing here?
For some reason generic square brackets in the code get interpreted as html commands and dont show up. I attached the sourcefiles to this post.