@Cacheable "注解类型不适用于这种声明"

Posted

技术标签:

【中文标题】@Cacheable "注解类型不适用于这种声明"【英文标题】:@Cacheable "annotation type not applicable to this kind of declaration" 【发布时间】:2013-10-14 17:32:45 【问题描述】:

我正在学习 Spring 和 Data JPA。我对 Ehcache 有疑问。我想缓存从数据库返回一些记录的方法之一的返回值。这是一个预先配置了 Ehcache 实例的练习(我假设)。问题是我不能使用注解@Cacheable 将我的方法标记为应该缓存其返回值的方法。我收到不兼容的类型编译错误(必需:布尔值,找到:字符串)。这是我认为应该将@Cacheable 放在这里的服务层中的一个类(对吗?):

package wad.datatables.service;

import javax.persistence.Cacheable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import wad.datatables.domain.Book;
import wad.datatables.repository.BookRepository;
import wad.datatables.view.DataTablesResponse;

@Service
public class JpaDataTablesBookService implements DataTablesBookService 

    @Autowired
    private BookRepository bookRepository;    

    @Override
    @Transactional(readOnly = true) 
    @Cacheable("books")
    public DataTablesResponse getBooks(String queryString) 
        Pageable pageable = new PageRequest(0, 10, Sort.Direction.ASC, "title");

        Page<Book> page = bookRepository.findByTitleContaining(queryString, pageable);

        DataTablesResponse response = new DataTablesResponse();
        response.setTotalRecords(page.getTotalElements());
        response.setTotalDisplayRecords(page.getNumberOfElements());
        response.setData(page.getContent());

        return response;
    

还有我的存储层(只有一个类):

package wad.datatables.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import wad.datatables.domain.Book;

public interface BookRepository extends JpaRepository<Book, Long>         
    Page<Book> findByTitleContaining(String title, Pageable pageable);

这是我的配置文件:

cache.xml(位于WEB-INF/spring/):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/cache 
            http://www.springframework.org/schema/cache/spring-cache.xsd">

    <cache:annotation-driven cache-manager="cacheManager" />

    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="ehcache"/>
    </bean>

    <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache.xml" />
    </bean>
</beans>

还有ehcache.xml(位于src/main/resources):

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:noNamespaceSchemaLocation="ehcache.xsd" 
         updateCheck="true" 
         monitoring="autodetect" 
         dynamicConfig="true">
    <cache name="books" maxEntriesLocalHeap="1000" eternal="true" memoryStoreEvictionPolicy="LRU"/>
</ehcache>

【问题讨论】:

【参考方案1】:

错误是因为您使用了错误的 Cacheable 注释。而不是javax.persistence.Cacheable 使用org.springframework.cache.annotation.Cacheable

【讨论】:

非常感谢!我对得到答案感到失望。由于提问的时间不合适(欧洲是午夜),我的问题在没有人看到的情况下被归为未回答的问题,我不能再问了,因为它会被标记为重复的问题!再次感谢你。但是如果 Spring 使用另一个与 java 的原始注解名称不同的注解不是更好吗?我使用了Netbeans的自动导入功能,不知道还有一个同名的注解。 如果名称必须有意义,则很难在整个 Java 生态系统中定义具有唯一名称的类(注解)。这就是为什么 Java 类由完整的类名(包名 + 类名)标识的原因。关于您的代码,它可以编译吗?根据 JEE documentation javax.persistence.Cacheable 不能应用于方法。

以上是关于@Cacheable "注解类型不适用于这种声明"的主要内容,如果未能解决你的问题,请参考以下文章

java缓存机制(上) map和spring注解@Cacheable

缓存注解介绍

为啥Spring对@Cacheable注解方法的单次调用执行@Cacheable keyGenerator 2次

Spring的Bean内部方法调用无法使用AOP切面(CacheAble注解失效)

spring boot cacheable在啥情况下不生效

@Cacheable 缓存注解的用法