hibernatecachingsecond-level-cachequery-cache

Cant understand how query cache and L2C works in hibernate


I configured Hazelcast as L2C for Hibernate. Then made 1st request using hibernate query builder with query cache hint and I got:

org.hibernate.engine.internal.StatisticalLoggingSessionEventListener:258 - Session Metrics {
    3263961 nanoseconds spent acquiring 1 JDBC connections;
    401548 nanoseconds spent releasing 1 JDBC connections;
    4244272 nanoseconds spent preparing 1 JDBC statements;
    6266312446 nanoseconds spent executing 1 JDBC statements;
    0 nanoseconds spent executing 0 JDBC batches;
    60891580391 nanoseconds spent performing 641667 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    8550 nanoseconds spent performing 1 L2C misses;
    0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
    0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}

Got puts in L2C. When I do 2nd request I got a ton of select queries with find by id.

Configurations for Hazelcast, Hibernate are simple, nothing complicated.

Entity is join table inheritance.

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) annotation used on superclass.

Checked Vlad Mihalcea article: https://vladmihalcea.com/hibernate-query-cache-n-plus-1-issue - proposals to avoid n+1 issue are not fully fits for my case.

Expected to get results from cache on second request but seems like I don't catch how query cache really works. Could someone explain step by step how query cache works ?


Solution

  • Hibernate does not store query result in the 'query' region as a whole; it rather stores set of ids, where the entities are in other 'entity' regions.

    My guess: If something is misconfigured and Hazelcast does not store the entities themselves, it's possible that while the list of entry ids is known from the query cache, it loads the actual entities one-by-one.

    Do the query and check sizes of cache regions.