Query only works correctly when debug printing results

#1

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.

#2

This might be normal behaviour. You should make data available before entity objects are detached.

See also this forum threads:

https://www.objectdb.com/issue/326

https://www.objectdb.com/forum/2032

 

ObjectDB Support
#3

Setting the fetch type of the List to eager via annotation solved the problem. Thanks.

Reply