I created an entity manager
I queried a list of entities
I called parallelStream on them, and called some getters which resulted in loading additional entities
I cleaned the entity manager
I repeated the process, and a NullPointerException was thrown during cleaning
Where MyEntity looks like:
The exception is thrown at StatefulPersistenceContext.java:234, which is:
While debugging I discovered that entityEntryContext.reentrantSafeEntityEntries() returned an array in which some elements were null.
The issue doesn't appear if I replace the parallelStream() with a simple stream().
JDK1.8, Windows 10, SQL Server
As of 5.2.13, this should work, provided that hibernate.jpa.compliance.proxy=false (default).
The reason it will work with this property setting because Hibernate will not initialize the lazy association when getting it's ID. If hibernate.jpa.compliance.proxy=true, then Hibernate will initialize the associated entities before returning the IDs.
Initializing the associations in parallel in separate threads will result in multi-threaded access to the EntityManager, which is not supported.
, , should the List returned by Query#getResultList be an implementation that overrides Collection#parallelStream to return a sequential stream?
No. In fact the usage here (concurrent access to a Session/EntityManager) is not supported.
, it's not obvious (at least to me) that the following could cause concurrent access to Session/EntityManager.:
It happens here because the entities are lazy and get initialized.
Collection#parallelStream Javadoc says:
"Returns a possibly parallel Stream with this collection as its source. It is allowable for this method to return a sequential stream."
I think it would be worth at least documenting that calling List#parallelStream on the List returned by Query#getResultList can cause problems if it contains lazy entities, associations, or properties.
I’ll close this as using an EntityManager concurrently is not supported (as Steve also said)