NullPointerException when cleaning an EntityManager which was used to load some entities in multiple threads

Description

Scenario:

  • 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

Stacktrace:

Test case:

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().

Environment

hibernate-core:5.2.10.Final
hibernate-envers:5.2.10.Final
hibernate-ehcache:5.2.10.Final
hibernate-c3p0:5.2.10.Final

JDK1.8, Windows 10, SQL Server

Activity

Show:
Gail Badner
March 1, 2018, 7:09 AM

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?

Steve Ebersole
March 2, 2018, 4:05 PM

No. In fact the usage here (concurrent access to a Session/EntityManager) is not supported.

Gail Badner
March 6, 2018, 6:30 AM

, 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.

Sanne Grinovero
August 19, 2020, 2:14 PM

I’ll close this as using an EntityManager concurrently is not supported (as Steve also said)

Assignee

Unassigned

Reporter

Severin Alexandru

Fix versions

None

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major
Configure