We're updating the issue view to help you get more done. 

Thread-unsafe behavior of Query Spaces in Named Queries

Description

Problem: Thread-unsafe behavior of query spaces in named queries
I catch ConcurrentModificationException sometimes when executing Native Queries.

Information:

  1. emf.addNamedQuery
    When we want to save Query with defined name we should use EntityManagerFactory#addNamedQuery
    This method build new NamedSQLQueryDefinition from saved Query.
    NamedSQLQueryDefinition created by NamedSQLQueryDefinitionBuilder

  2. NamedSQLQueryDefinitionBuilder
    NamedSQLQueryDefinitionBuilder use method createNamedQueryDefinition for NamedSQLQueryDefinition build.
    This method use querySpacesCopy() for safe copying of elements from querySpaces.

  3. em.createNamedQuery
    When we want to create new instance of Query by name we should use EntityManager#createNamedQuery
    We get NamedSQLQueryDefinition from NamedQueryRepository by query name.
    Version 5.1.14:
    Our new query (new SQLQueryImpl) will get NamedSQLQueryDefinition
    Also, new query get all query spaces: this.querySpaces = queryDef.getQuerySpaces();
    Version 5.3.0:
    The same behavior in NativeQueryImpl class

  4. Thead-safe or not Thread-safe?
    SQLQueryImpl copy reference to NamedSQLQueryDefinition query spaces collection, not makes copy (like NamedSQLQueryDefinitionBuilder).
    So, every Named Query created by the same name share one query spaces collection.
    It's not thread safe, not obvious and unpredictably.

Suggestion: create a copy of query spaces in SQLQueryImpl constructor with NamedSQLQueryDefinition

Links:
Version 5.1.14 source code:
https://github.com/hibernate/hibernate-orm/blob/5.1.14/hibernate-core/src/main/java/org/hibernate/internal/SQLQueryImpl.java#L85
Version 5.3.0.Final source code:
https://github.com/hibernate/hibernate-orm/blob/5.3.0.Final/hibernate-core/src/main/java/org/hibernate/query/internal/NativeQueryImpl.java#L85

To reproduce the error:

  1. Import Gradle project from

  1. Perform tests from AppTest test class.

Environment

hibernate-core, gradle, JDK 8

Status

Assignee

Guillaume Smet

Reporter

Роджер Весёлый

backPortable

Backport?

Components

Fix versions

Affects versions

5.1.13
5.3.0.Final

Priority

Minor