hibernate Infinispan 2LC : query cache and entity cache in same cache region

标签 hibernate infinispan wildfly-10 second-level-cache

使用 JBoss Cache,可以存储 entity缓存和 query缓存在同一缓存区域中没有任何问题。但是一旦迁移到wildfly 10(infinispan为2LC),似乎就有问题了。

我已经为实体提供了缓存区域,如下所示。

@Entity     
@Cacheable  
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY, 
     region="regionA")
public class EntityXYZ{

查询缓存为

 entManager.createQuery(
        "....")
    .setHint("org.hibernate.cacheable", true)
    .setHint("org.hibernate.cacheRegion", "regionA").getResultList();

需要注意的是上面的query还包含entities它们本身被声明为 cacheable并具有与 regionA 相同的缓存区域.

现在执行时,出现此错误。我怀疑这是由于冲突,因为它们存储在同一区域,并且它尝试获取返回另一个对象的对象 ID。但有人可以照亮吗?真的是这样吗?并解释有关错误的更多信息?

但是在JBoss 5中的JBoss缓存中也同样有效。 。是infinispan处理方式不同?或者是这个Hibernate问题?

ERROR [org.jboss.as.ejb3.invocation] (default task-8) WFLYEJB0034: EJB Invocation failed on component... javax.ejb.EJBTransactionRolledbackException: Object [id=4] was not of the specified subclass [ com.abc.xyz] : loaded object was of wrong class class  com.abc.yyy
                at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:159)
                at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:256)

     [org.hibernate.event.internal.DefaultLoadEventListener] (default task-8) HHH000327: Error performing load command : org.hibernate.WrongClassException: Object [id=4] was not of the specified subclass [com.abc.xyz] : loaded object was of wrong class class com.abc.yyy

更新:

entitymanager尝试加载具有 @id 的 2 个此类(在同一共享缓存 2LC 区域中)的不同调用如int 。正如弗拉维乌斯指出的那样,id=4似乎在两个类之间很常见。

将以下配置添加到 persistence.xml 时,出现启动错误。

persistence.xml

<property name="hibernate.cache.keys_factory" value="default" />

错误

 javax.persistence.PersistenceException: [PersistenceUnit: app-entity] Unable to build Hibernate SessionFactory
            at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:179)
            at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:121)
            at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:667)
            at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:193)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at java.lang.Thread.run(Thread.java:745)
            at org.jboss.threads.JBossThread.run(JBossThread.java:320)
    Caused by: javax.persistence.PersistenceException: [PersistenceUnit: app-entity] Unable to build Hibernate SessionFactory
            at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954)
            at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882)
            at org.jboss.as.jpa.hibernate5.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44)
            at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:161)
            ... 7 more
    Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.spi.CacheImplementor]
            at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:264)
            at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:228)
            at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:207)
            at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:242)
            at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
            at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879)
            ... 9 more
    Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [default] as strategy [org.hibernate.cache.spi.CacheKeysFactory]
            at org.hibernate.boot.registry.selector.internal.StrategySelectorImpl.selectStrategyImplementor(StrategySelectorImpl.java:113)
            at org.hibernate.boot.registry.selector.internal.StrategySelectorImpl.resolveDefaultableStrategy(StrategySelectorImpl.java:162)
            at org.hibernate.boot.registry.selector.internal.StrategySelectorImpl.resolveDefaultableStrategy(StrategySelectorImpl.java:126)

更新2

我已更改为提供 default确切地说FQN ,但是它不起作用。该错误不正确,因为该类是指定类的实现。

<property name="hibernate.cache.keys_factory" value="org.hibernate.cache.internal.DefaultCacheKeysFactory" />

错误:

Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.spi.CacheImplementor]
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:264)
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:228)
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:207)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:242)
        at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879)
        ... 9 more
Caused by: java.lang.ClassCastException: org.hibernate.cache.internal.DefaultCacheKeysFactory cannot be cast to org.hibernate.cache.spi.CacheKeysFactory
        at org.hibernate.cache.infinispan.InfinispanRegionFactory.determineCacheKeysFactory(InfinispanRegionFactory.java:427)
        at org.hibernate.cache.infinispan.InfinispanRegionFactory.start(InfinispanRegionFactory.java:378)
        at org.hibernate.internal.CacheImpl.<init>(CacheImpl.java:49)
        at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:28)
        at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:20)
        at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:46)
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:254)

最佳答案

查询缓存是字符串索引的,实体缓存是使用原始 ID 进行索引的(与 EntityXYZ 中用 @Id 标记的字段/方法相同的对象),所以我想知道冲突是如何发生的发生在id=4

无论如何,对实体和查询使用相同的区域(缓存)并不是一个好主意 - 实体有时需要更复杂的处理来实现数据库样式的隔离。这种组合在 Hibernate 6 中可能根本不可能实现。除非在多个线程中运行压力测试,否则您可能不会遇到问题,顺序调用通常可以正常工作。

如果你坚持将它们存储到同一个缓存中,你可以尝试设置 hibernate.cache.keys_factory=default (我希望你的 WF 版本已经包含此设置,较新的版本应该已经包含它默认)。

参见https://hibernate.atlassian.net/browse/HHH-11083https://hibernate.atlassian.net/browse/HHH-10287了解详情。

关于 hibernate Infinispan 2LC : query cache and entity cache in same cache region,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43939988/

相关文章:

java - Hibernate 和 PostgreSQL 中具有 UserType 的数组 --> MappingException

java - 使用树缓存进行 Infinispan 驱逐

java - 如何为JPA L2缓存配置WIldfly infinispan子系统?

Java Hibernate在插入用户名和密码时获取实体ID并将其删除

java - 无法初始化代理 - hibernate - grails - Multi-Tenancy

java - 为什么没有读取 JPA find() 方法未提交的更改?

server - 如何在 Wildfly 配置文件中使用变量?

wildfly - 通过配置禁用 Google Analytics for Wildfly

hibernate - JPA 查询 org.hibernate.QueryException : could not resolve property

postgresql - Keycloak Docker 集群未从 JDBC_PING 数据库中删除