我最近将我的java应用程序从hibernate 4.1升级到hibernate 5.2,我注意到(通过查看SQL跟踪)第二级实体缓存使用情况的差异。缓存不会像以前的版本那样经常使用。
为了简单起见,假设我有一个非常基本的模型:与其父母有多对一关系的儿童实体。 PARENT类使用@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
进行注释。 CHILD中的多对一关系用@Fetch(FetchMode.SELECT)
注释。这应该让第二级缓存有机会在获取CHILD时存储PARENT。
当我加载单个CHILD实例(使用from CHILD where id=:id
之类的查询)时,我看到使用了PARENT缓存。如果我再次执行查询,则PARENT辅助选择不会重复到数据库。
但是,当我一次加载多个CHILD时(使用from CHILD
之类的查询),不使用PARENT缓存。如果我再次执行查询,则重复次要PARENT选择。
这是表演的一大损失。有人遇到过同样的问题吗?我错过了一些配置部分吗?
感谢您的帮助。
答案 0 :(得分:1)
在我花费更多时间在这个问题上之后,我发现它是由在读取多个CHILD之前执行的本机查询引起的。此本机查询在数据库会话(SET LOCAL TIME ZONE '<TIMEZONEID>'
)中设置一个参数,该参数用于对用户时区中的日期进行一些计算。
读取的CHILDs方法使用@Transactional(readOnly = true)
注释,但在会话中设置时区参数需要调用query.executeUpdate()
,尽管它不会更改实体。这似乎是导致缓存停止存储实体的原因。
我仍然在寻找一种解决方法,但我知道它与特定的hibernate版本无关,也不能同时读取多个CHILD。