gpt4 book ai didi

hibernate - Hibernate Cache Annotation区域属性不起作用

转载 作者:行者123 更新时间:2023-12-02 01:52:40 25 4
gpt4 key购买 nike

我有一个使用Hibernate二级缓存和查询缓存的spring / springwebflow(应用程序A)应用程序。该应用程序仅从数据库中读取,而无法添加/更新/删除语句。

查询被缓存到一个称为“daoCache”的区域。我已经通过namedQuerys上的注释设置了它

我也有一个来自Hibernate @Cache的注释的实体,它的属性区域也设置为“daoCache”

@Entity
@Table(name = "GROUP_OPERATOR")
@SequenceGenerator(name = "SEQ_GROUP_OPERATOR", sequenceName = "SEQ_GROUP_OPERATOR")
@NamedQueries( {
@NamedQuery(name = "findGroupOperatorByMaster", query = "FROM GroupOperator groupOperator WHERE groupOperator.segment IS NULL and groupOperator.pointsMaster.pointMaster like ?",
hints={@QueryHint(name="org.hibernate.cacheRegion", value="daoCache"),
@QueryHint(name="org.hibernate.cacheable", value="true")})
})
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region = "daoCache")
public class GroupOperator implements Serializable{
....

除此之外,我还有另一个应用程序(应用程序B),该应用程序连接到同一数据库并在同一数据库上执行添加/更新/删除操作

因此,我们将限制设置为20分钟以刷新应用程序A上的缓存区域。因此,在应用程序B中所做的更改会在20分钟后反映在应用程序A中。

因此,假设应用程序A执行查询“从group_operator中选择*,其中point_master = 1000”。该查询将与结果标识符一起保存在缓存中,例如groupOperator#1。因此,该查询执行的任何其他时间(20分钟之间)都将从缓存中返回标识符#1。并且该实体还将保存在相同的缓存区域中。

问题是应用B删除记录并创建新记录(具有不同的ID) ,但*具有与查询中的参数相同的值*

因此,在20分钟内,应用程序A将返回实体groupOperator#1,并且应用程序日志中未显示任何select语句。这是预期的行为。

20分钟后,缓存将被重置。

现在,应用程序A尝试执行相同的查询(“从group_operator中选择*,其中point_master = 1000”)。它将对数据库进行查询,因为20分钟后缓存被清除。因此,结果应该是在App B中创建的新ID。但是相反,我得到了ObjectNotFoundException不存在具有给定标识符的行:groupOperator#1

即使select语句也显示在日志中,但仍返回旧的实体标识符。当然,ID 1不再在数据库中。

这很奇怪,因为我认为清理缓存将再次执行查询

如果实体和查询都缓存在同一区域中,为什么仍在寻找旧实体?

经过几天的调查,使用堆转储,我发现该实体未缓存在@Cache注释中指定的“daoCache”上。但是正在缓存在名为“xxx.xxx.xxx.xx.groupOperator”的新区域上。似乎该注释的属性不起作用。

我有一些问题

1-为什么“缓存注释”中的“区域”属性不起作用?即使我设置“daoCache”也可以保存在另一个?这是休眠的错误吗?

2-查询缓存的工作原理如何?我的意思是,如果再次执行查询,则它应返回新标识符,然后使用该新标识符,休眠应执行load方法并解决问题。但是仍然尝试从旧的标识符加载。

这是我的实际ehcache.xml配置
<cache name="daoCache" maxElementsInMemory="30000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true">
</cache>

<cache name="rwCache" maxElementsInMemory="30000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true">
</cache>

<cache name="xxx.xxxx.xxx.xxxx.groupOperator" maxElementsInMemory="30000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true">
</cache>

这是我的缓存提供者
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>

使用以下版本的休眠
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>3.3.2.GA</version>
</dependency>


<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.2.GA</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations
</artifactId>
<version>3.2.0.Final</version>
</dependency>

谢谢你的时间

更新:

我没有指定任何hibernate.cache.region.factory_class。所以我想使用的是默认值。不知道哪个是默认值

这些查询在Class中具有注释queryhint。即使我从表中删除了所有记录,但仍在不对数据库执行任何选择的情况下仍返回旧记录,这仍然可以很好地缓存查询。因此查询缓存效果很好。

问题是:...

删除表上的所有记录并确认查询缓存可以正常工作后,我向同一表添加了一条新记录,其值与以前相同,但主ID不同

清除缓存后(自动在20分钟后),该查询将再次在数据库上执行(没关系,我可以在日志中看到select语句)。在表中找到新记录,该记录应返回一个标识符,然后将整个实体加载到内存中。奇怪的是,当它试图将整个实体放入内存时,它正在使用旧标识符而不是我之前添加的新标识符来寻找该实体。就像查询,即使再次通过数据库执行一样,仍在返回旧的标识符。但是我重复一遍,查询缓存在其他情况下仍能正常工作,这是肯定的。

因此,我不了解查询缓存和实体缓存如何协同工作。就像查询缓存和实体缓存之间存在问题。我之所以这样说是因为我通过在ehcache.xml中添加该实体的区域配置来解决此问题。
<cache
name="com.citi.latam.business.services.dao.model.db.campaign.groupOperator"
maxElementsInMemory="30000" eternal="false" timeToIdleSeconds="120"
timeToLiveSeconds="120" overflowToDisk="true">
</cache>

最佳答案

固定!

我终于解决了。
首先,我要做的是从hibernate和ehcache启用所有调试

在日志中搜索时,我发现数据库模型的配置不正确

对象GroupOperator具有一个称为Calendar的属性。
问题在于对象Calendar还具有带有Cache批注的GroupOperator列表。因此,每次Hibernate获得新的GroupOperator时,也想刷新子实体,例如Calendar,但是Calendar有自己的GroupOperator列表,并且子实体似乎不在同一缓存区域中或以不同的方式工作。

问题解决了!
感谢您的宝贵时间@jhadesdev,对继续调查此事很有帮助。

问候,

关于hibernate - Hibernate Cache Annotation区域属性不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21837841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com