2017-05-12 16 views
2

JBoss Cacheを使用すると、同じキャッシュ領域にentityキャッシュとqueryキャッシュを問題なく格納できました。しかし、一度wildfly 10に移行すると(infinispanを2LCとして)、問題があるようです。Hibernate Infinispan 2LC:同じキャッシュ領域内のクエリキャッシュとエンティティキャッシュ

エンティティのキ​​ャッシュ領域を以下のように指定しました。

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

として

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

とクエリキャッシュは上記queryも自身がcacheableとして宣言し、regionAと同じキャッシュ領域を有しているentitiesが含まれていることに注意することが重要です。

実行中にこのエラーが発生しました。私は、同じリージョンに格納されているので、別のオブジェクトを返すオブジェクトIDを取得しようとするため、競合が原因であると思われます。しかし誰かが光を投げることができます。これは事実ですか?エラーの詳細を説明してください。

しかし、同じことがJBossキャッシュのJBoss 5で機能します。 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 

UPDATE:intとして@idを有する(同じ共有キャッシュ2LC領域における)2つのこのようなクラスの異なる呼び出しでロードする

entitymanager試みます。 Flaviusが指摘したように、id=4は2つのクラスの間で共通するようです。

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) 

UPDATE 2

しかし私はそれがない、FQNを強要するdefaultを提供するために変更されましたうまくいかない。クラスが指定されたクラスの実装であるため、エラーは正しくありません。

<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) 
+0

JIRAによると、DefaultCacheKeysFactoryの問題は5.0.12,5.1.3および5.2.5で修正されているようです。通常、手動でWFのhibernate-ormモジュールを5.0.12に更新することができます(マイクロバージョンの場合と同様)。 –

+0

ありがとうございます。共有キャッシュ領域のためにパフォーマンスが向上しない場合は、ベストプラクティスのみを使用します。 – ulab

答えて

3

クエリキャッシュは、文字列インデックスであり、エンティティ・キャッシュがいずれかの生のIDを使用して(EntityXYZに@Idでマークされたフィールド/メソッドと同じオブジェクト)をインデックス付けされますだから私はどのように紛争が起こる可能性があるのだろうid=4

とにかく、エンティティとクエリに同じ領域(キャッシュ)を使用することはお勧めできません。エンティティは、DBスタイルの分離を実現するためにより複雑な処理を必要とすることがあります。そのような組み合わせは、Hibernate 6ではまったく不可能かもしれません。多くのスレッドでストレステストを実行するまで、問題は発生しません。通常、順次呼び出しは正常に動作します。

hibernate.cache.keys_factory=defaultを設定してみるといいでしょう(あなたのWFバージョンにはすでにこの設定が含まれていて、新しいバージョンでは既定値として使用してください)。

詳細については、https://hibernate.atlassian.net/browse/HHH-11083およびhttps://hibernate.atlassian.net/browse/HHH-10287を参照してください。

+1

ありがとうございます。提案したデフォルトのキャッシュキー実装を追加しました。スタートアップ時に、 '名前[デフォルト]を戦略[org.hibernate.cache.spi.CacheKeysFactory]'として解決できませんでした。私はWF 10.1に付属のデフォルトの休止状態(5.0.10)とInfinispan(8.2.4)を使用しています。 – ulab

+0

私は私の質問にUPDATEを追加しました。あなたは正しいです。この問題は、同じ領域内のクエリキャッシュとエンティティキャッシュでは発生しません。しかし、同じ地域の共有エンティティキャッシュが原因です。 entitymanager.find(EntityXYZ.class、4)は、期待されるものとは異なるオブジェクトを返します。そして、私は、説明されている解決策は5.0.xのバージョンでは修正されていないと思います。 – ulab

+0

また、すべてのエンティティを共有キャッシュ領域に保持するのは嫌いです。しかし、私はすべてのエンティティに共有キャッシュ領域を採用している以前のJBossキャッシュバージョンより3倍速くアプリケーションを実行することができます。エンティティが別々の共有キャッシュ領域にキャッシュされていると、パフォーマンスが向上しますか?パフォーマンスを向上させるための設定は非常に高く評価されます。おかげで – ulab

関連する問題