9

100 以上のエンティティ クラスを持つ広範なエンティティ モデルがあります。すべてのエンティティ クラスは、単一のエンティティ スーパークラスのサブクラスです。共有キャッシュ モードはALLに設定されています。

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "entities")
public abstract class LongIdEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.TABLE)
  private Long id;

  @Version
  @Column(name = "OPT_LOCK_VERSION")
  private Long lockVersion;

  etc...

}

サブクラスの例:

@Entity
@Table(name = "cars")
public class Car extends LongIdEntity { ... }

すべてのエンティティを第 2 レベルのキャッシュにキャッシュしたいと考えています。問題は、すべてのエンティティに対して 1 つのキャッシュ領域しか作成されないことです。LongIdEntityという名前です。

デバッグは、Hibernateすべてのエンティティ クラスを見つけたことを示していますが、とにかくそれらに同じリージョンを割り当てます。SessionFactoryImpl:339で:

String cacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName();

私たちの場合、model.getRootClass()への呼び出しは常に " LongIdEntity " を生成します。

これにより、実際にすべてのエンティティがキャッシュされると思いますが、エビクションの制御はありません。一部のクラスは非常に頻繁で読み取り専用です。そのため、それらをメモリに固定しておきたいと考えています。一部は通常、特定の期間などに使用されます...すべてを同じキャッシュに詰め込むと、すべてが無効になります。

注釈で領域を指定しても効果はありません。例えば:

@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,region = "cars")
@Entity
@Table(name = "cars")
public class Car extends LongIdEntity { ... }

奇妙なことに、共有キャッシュ モードALLのみがエンティティ クラスを取得します。他のモードでは、 @Cache および/または @Cacheable で注釈が付けられている場合でも、エンティティはありません。多分これは兆候ですか?

特定のエンティティクラスを特定の地域に割り当てる方法を誰かが知っていますか?

ティア:-)

persistence.xmlは基本的なものです。

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="cars" transaction-type="RESOURCE_LOCAL">
    <shared-cache-mode>ALL</shared-cache-mode>
  </persistence-unit>
</persistence>

セッション ファクトリは、古典的な方法で作成されます。

  <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
    <property name="persistenceUnitName" value="optimus"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaProperties">
      <props>
        <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
        <prop key="hibernate.cache.use_second_level_cache">true</prop>
        <prop key="hibernate.cache.use_query_cache">true</prop>
        <prop key="hibernate.generate_statistics">true</prop>
        <prop key="hibernate.cache.default_cache_concurrency_strategy">NONSTRICT_READ_WRITE</prop>
        <prop key="hibernate.hbm2ddl.auto">update</prop>
        <prop key="hibernate.jdbc.batch_size">1000</prop>
        <prop key="hibernate.show_sql">false</prop>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
        <prop key="hibernate.search.default.directory_provider">filesystem</prop>
        <prop key="hibernate.search.default.indexBase">/hibernate-search</prop>
      </props>
    </property>
  </bean>

環境

  • JDK6
  • Linux x64
  • 休止状態 4.1.10
  • 春 3.2.1

更新: @MappedSuperclass を使用

@MappedSuperclass
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class LongIdEntity { ... }

何も変わらない。

4

2 に答える 2

11

Hibernateは、エンティティ階層全体を1つのリージョンに明示的にキャッシュします。これを制御することはできません。多態的ルックアップのキャッシュされた解決を適切に処理する唯一の方法です。他のプロバイダー(私は思う)は、各サブクラスがキャッシュされる場所/方法をある程度制御することを許可しています(少なくとも、JPAによって提供されるオプションに基づく私の推測です)。

于 2013-03-16T16:12:28.590 に答える