Uploaded image for project: 'Hibernate ORM'
  1. HHH-12621

Thread-unsafe behavior of Query Spaces in Named Queries

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 5.1.13, 5.3.0.Final
    • Fix Version/s: 5.2.18, 5.3.1
    • Component/s: hibernate-core
    • Labels:
      None
    • Environment:
      hibernate-core, gradle, JDK 8
    • Bug Testcase Reminder (view):

      Bug reports should generally be accompanied by a test case!

    • backPortable:
      Backport?
    • Last commented by a user?:
      true
    • Sprint:

      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 HibernateThreadUnsafeSample.rar
      2. Perform tests from AppTest test class.

        Attachments

          Activity

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: