Uploaded image for project: 'JBoss Enterprise Application Platform 4 and 5'
  1. JBoss Enterprise Application Platform 4 and 5
  2. JBPAPP-4224

Query Cache effective only after closing the session that created the cache

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Major
    • EAP_EWP 5.1.0
    • EAP 5.0.1
    • Hibernate
    • None
    • Release Notes
    • Hide

      Close the session/entity manager and open again. This refreshes the timestamp value for the session, causing subsequent calls to a cached query to be retrieved without hitting the database.

      Show
      Close the session/entity manager and open again. This refreshes the timestamp value for the session, causing subsequent calls to a cached query to be retrieved without hitting the database.

    Description

      When using a query which is marked as cacheable, Hibernate caches both the query and the timestamp in the cache, but uses two different timestamps for that. When retrieving a query from the cache, it first compares the timestamp of the cached query with the timestamp of the current session (UpdateTimestampsCache.isUpToDate()):

      if ( lastUpdate.longValue() >= timestamp.longValue() ) {
      return false;
      }

      The problem is that the timestamp for the current session is always lower than cache's timestamp if the cache was created with the same session, causing the result of the method to be "false", discarding the cache results and hitting the database.

      It's not clear where the bug is, but it's worth looking at some considerations:

      1) Why is it comparing the cache's timestamp with session's timestamp? The cache itself can expire the data via timeout and Hibernate should expire the data if any relevant table was changed (both are happening). Besides, I wasn't able to think of a single use case where the cached data could be considered "outdated" just because its timestamp is higher than the current session's timestamp (meaning that they are newer than the session).

      2) The javadoc for the SessionImplementor.getTimestamp() says:
      "System time before the start of the transaction"
      So, someone consuming this method can assume that this timestamp is related to the transaction. If the timestamp was related to the transaction, then the cache's timestamp would never be higher than session's. Then, this comparison would make sense, to not return something which would never happen and is probably wrong.

      So, it's up to the developers to decide what's wrong:

      • JavaDoc + the logic to get a timestamp which is used when creating the query cache
      • getTimestamp() value + UpdateTimestampsCache.isUpToDate logic + other places relying in the wrong return value

      Attachments

        Activity

          People

            shaozliu Strong Liu(刘少壮) (Inactive)
            jpkroehling@redhat.com Juraci Paixão Kröhling (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: