Região de cache dedicada para subclasses de entidade?

Temos um modelo de entidade extenso com mais de 100 classes de entidade. Todas as classes de entidade são subclasses de uma única superclasse de entidade. O modo de cache compartilhado foi definido comoTODOS.

@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...

}

Uma subclasse de exemplo:

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

Gostaríamos de armazenar em cache todas as entidades no cache do segundo nível. O problema é que apenas uma região de cache é feita para todas as entidades; nomeadoLongIdEntity.

Depuração mostra o Hibernatefez encontrar todas as classes de entidade, mas atribui-lhes a mesma região de qualquer maneira. Porque aSessionFactoryImpl: 339 :

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

No nosso caso, a chamada paramodel.getRootClass () sempre renderá "LongIdEntity".

Eu presumo que isso realmente armazene todas as entidades, mas sem qualquer controle de despejo. Algumas classes são muito freqüentes e somente leitura. Então, queremos mantê-los presos na memória. Alguns são normalmente usados ​​em um determinado período de tempo, etc ... Cramming tudo no mesmo cache invalida tudo.

Especificar a região na anotação não tem efeito. Por exemplo:

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

O estranho é que apenas o modo de cache compartilhadoTODOS pega as classes de entidade. Em qualquer outro modo, nenhuma entidade é - mesmo quando anotada com @Cache e / ou @Cacheable. Talvez isso seja uma indicação?

Alguém tem uma ideia de como eu posso designar regiões específicas de classes específicas?

TIA :-)

persistence.xml é elementar:

<?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>

A fábrica da sessão é feita da maneira clássica:

  <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>

O ambiente

JDK6Linux x64Hibernate 4.1.10Primavera 3.2.1

UPDATE: Use @MappedSuperclass

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

Não muda nada também.

questionAnswers(2)

yourAnswerToTheQuestion