Java 使用Spring 4@Transactional+;忽略缓存;冬眠4+;二级缓存

Java 使用Spring 4@Transactional+;忽略缓存;冬眠4+;二级缓存,java,spring,hibernate,caching,ehcache,Java,Spring,Hibernate,Caching,Ehcache,几天以来,我在Spring上下文中使用@Transactional注释进行Hibernate缓存,结果被阻止了 我尝试了在网上找到的所有解决方案,但没有成功 唯一可行的解决方案是使用@Cacheable-Spring注释(来自Spring上下文支持),但我并不满意,因为我无法在实体上使用Hibernate@Cache注释。 @Cacheable只能用于服务方法之类的方法,我检索实体时不使用方法 例如: 我调用以下获取集合实体的服务 @Override @Transactional(readOnl

几天以来,我在Spring上下文中使用@Transactional注释进行Hibernate缓存,结果被阻止了

我尝试了在网上找到的所有解决方案,但没有成功

唯一可行的解决方案是使用@Cacheable-Spring注释(来自Spring上下文支持),但我并不满意,因为我无法在实体上使用Hibernate@Cache注释。 @Cacheable只能用于服务方法之类的方法,我检索实体时不使用方法

例如:

我调用以下获取集合实体的服务

@Override
@Transactional(readOnly = true)
public CollectionEntity getById(Integer collectionId) throws Exception {
    if(collectionId < 1) {
        logger.debug("Cannot retrieve a collection from identifier inferior to 1.");
        return null;
    }
    return collectionDao.getById(collectionId);
}
因此,如果我想缓存ChannelEntity,我通常只需要在它的类上添加以下注释

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "Channel")
@Table(name = ChannelEntity.TABLE)
public class ChannelEntity implements java.io.Serializable {
对于参考数据,“急切”抓取是一个非常有吸引力的解决方案!但是,如果a想使用@Cacheable,这是目前唯一的解决方案,我必须用FetchType.LAZY声明ChannelEntity,并编写一个服务类,将@Cacheable放在它上面,以便缓存此数据。 这是个笑话。。。我不会对所有引用数据类都这样做

真正的解决方案是在ChannelEntity上放置一个工作的Hibernate@Cache注释

为了让它正常工作,我甚至开发了自己的“SingletonEhCacheRegionFactory”类,并使用Spring类“EhCacheManagerFactoryBean”作为缓存管理器进行初始化。
数据继续从数据库中提取。这个解决方案对我的一位同事有效,但对于较旧版本的Spring(second-level和query-cache),它有一些看起来奇怪的行为,但实际上是正常的

例如,实体上的
@Cache
将仅缓存按Id加载的实体。如果要缓存除按Id加载外的查询结果,则需要将查询标记为可缓存:

@NamedQuery(name="account.queryName",
   query="select acct from Account ...",
   hints={
       @QueryHint(name="org.hibernate.cacheable",
       value="true")
   }     
})
或在条件查询的情况下:

List cats = session.createCriteria(Cat.class)
    .setCacheable(true)
    .list();
默认情况下,一对多关系也不会缓存。如果要缓存关联,则需要使用
@cache
单独标记它们。例如:

@Cache(CacheConcurrencyStrategy.READ_WRITE)
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<ProgramEntity> programs = new HashSet<ProgramEntity>(0);
@Cache(cacheconcurrencystategy.READ\u WRITE)
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
私有集程序=新哈希集(0);

第二级缓存和查询缓存有一些看似奇怪的问题,但实际上是正常的

例如,实体上的
@Cache
将仅缓存按Id加载的实体。如果要缓存除按Id加载外的查询结果,则需要将查询标记为可缓存:

@NamedQuery(name="account.queryName",
   query="select acct from Account ...",
   hints={
       @QueryHint(name="org.hibernate.cacheable",
       value="true")
   }     
})
或在条件查询的情况下:

List cats = session.createCriteria(Cat.class)
    .setCacheable(true)
    .list();
默认情况下,一对多关系也不会缓存。如果要缓存关联,则需要使用
@cache
单独标记它们。例如:

@Cache(CacheConcurrencyStrategy.READ_WRITE)
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<ProgramEntity> programs = new HashSet<ProgramEntity>(0);
@Cache(cacheconcurrencystategy.READ\u WRITE)
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
私有集程序=新哈希集(0);

第二级缓存和查询缓存有一些看似奇怪的问题,但实际上是正常的

例如,实体上的
@Cache
将仅缓存按Id加载的实体。如果要缓存除按Id加载外的查询结果,则需要将查询标记为可缓存:

@NamedQuery(name="account.queryName",
   query="select acct from Account ...",
   hints={
       @QueryHint(name="org.hibernate.cacheable",
       value="true")
   }     
})
或在条件查询的情况下:

List cats = session.createCriteria(Cat.class)
    .setCacheable(true)
    .list();
默认情况下,一对多关系也不会缓存。如果要缓存关联,则需要使用
@cache
单独标记它们。例如:

@Cache(CacheConcurrencyStrategy.READ_WRITE)
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<ProgramEntity> programs = new HashSet<ProgramEntity>(0);
@Cache(cacheconcurrencystategy.READ\u WRITE)
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
私有集程序=新哈希集(0);

第二级缓存和查询缓存有一些看似奇怪的问题,但实际上是正常的

例如,实体上的
@Cache
将仅缓存按Id加载的实体。如果要缓存除按Id加载外的查询结果,则需要将查询标记为可缓存:

@NamedQuery(name="account.queryName",
   query="select acct from Account ...",
   hints={
       @QueryHint(name="org.hibernate.cacheable",
       value="true")
   }     
})
或在条件查询的情况下:

List cats = session.createCriteria(Cat.class)
    .setCacheable(true)
    .list();
默认情况下,一对多关系也不会缓存。如果要缓存关联,则需要使用
@cache
单独标记它们。例如:

@Cache(CacheConcurrencyStrategy.READ_WRITE)
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<ProgramEntity> programs = new HashSet<ProgramEntity>(0);
@Cache(cacheconcurrencystategy.READ\u WRITE)
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
私有集程序=新哈希集(0);

杰德斯戴夫真是太酷了

我为实体、实体的FetchType.EAGER属性和查询定义了EHCache缓存

然后,我在实体及其FetchType.EAGER属性上添加了@Cache注释。 我还在服务中添加了“cacheable”属性,允许检索定义为FetchType.LAZY的实体属性的值以及我的其他查询

一切正常


非常感谢您为我提供了实现缓存所缺少的概念!!!:-)

真是太酷了

我为实体、实体的FetchType.EAGER属性和查询定义了EHCache缓存

然后,我在实体及其FetchType.EAGER属性上添加了@Cache注释。 我还在服务中添加了“cacheable”属性,允许检索定义为FetchType.LAZY的实体属性的值以及我的其他查询

一切正常


非常感谢您为我提供了实现缓存所缺少的概念!!!:-)

那真是太酷了贾德斯德夫

我为实体、实体的FetchType.EAGER属性和查询定义了EHCache缓存

然后,我在实体及其FetchType.EAGER属性上添加了@Cache注释。 我还在服务中添加了“cacheable”属性,允许检索定义为FetchType.LAZY的实体属性的值以及我的其他查询

一切正常


非常感谢您为我提供了实现缓存所缺少的概念!!!:-)

那真是太酷了贾德斯德夫

我为实体、实体的FetchType.EAGER属性和查询定义了EHCache缓存