There are only two hard things in Computer Science: cache invalidation and naming things.
– Phil Karlton
According to beikov in this post Hibernate ORM 6 currently stores the full data for query caches. I am really interested in how Hibernate invalidates this query cache, both in the current version 6.2 and in the future version 6.5.
Let’s say we have 2 enitites Post and Comment:
@Cache(region = "post-cache", usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name = "post")
public class Post implements Serializable {
@Id
@Column(name = "post_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long postId;
@OneToMany(mappedBy = "post", fetch = FetchType.LAZY)
private List<Comment> comments = new ArrayList<>();
}
@Cache(region = "comment-cache", usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name = "comment")
public class Comment implements Serializable {
@Id
@Column(name = "comment_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long commentId;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "post_id")
private Post post;
}
And then we have a Repository for Post:
public interface PostRepository extends JpaRepository<Post, Long> {
@QueryHints(value = {
@QueryHint(name = HibernateHints.HINT_CACHEABLE, value = "true"),
@QueryHint(name = HibernateHints.HINT_CACHE_REGION, value = "post-query-cache")
}, forCounting = false)
@EntityGraph(type = EntityGraph.EntityGraphType.FETCH, attributePaths = "comments")
@Query("""
SELECT post
FROM Post post
WHERE post.postId = :postId
""")
Optional<Post> findByPostId(@Param("postId") Long postId);
As you can see, the query method is told to fetch the comments as well. Now, this setup works fine in Hibernate 6.2. But how does Hibernate decide when to clear/invalidate the query cache? Here my questions:
- Does Hibernate take the
EntityGraph
into account to track related entities for cache invalidation? - Does Hibernate invalidate the query cache every time an existing
Comment
gets updated or deleted? - Does Hibernate depend somehow on a specific way
Comment
gets updated, e.g. viadirty check
, or is there no concern at all?
To summarize my concerns:
-
Does Hibernate take care of all possibilities and can I rely on Hibernate, so that
Comment
s in the related collection of thePost
entity are always up to date when I use the query cache, even when the collection is markedFetchType.LAZY
? -
Am I right that starting with Hibernate v6.5 all these concerns will disappear, since from this point on Hibernate will only store the related entity-id in the query cache and will then try to rehydrate the entity directly from its dedicated entity cache?
Specific question for upcomming ORM 6.5:
- Will I have to annotate the collection in the Post entity for proper collection caching, even when I only use query cache?
Many thanks for any clarification.
Cheers, Slevin