首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对返回Hibernate对象的方法使用Spring的Cachable注释

对返回Hibernate对象的方法使用Spring的Cachable注释
EN

Stack Overflow用户
提问于 2015-08-20 05:57:34
回答 1查看 819关注 0票数 0

我昨天安装了Memcached,并最终使Spring @Cachable注释工作..。

这个代码块完美地缓存:

代码语言:javascript
复制
@Component("CacheProcessor")
public class CacheProcessor {
    @Cacheable(value = "defaultCache", key="'dateTime-'.concat(#anything)")
    public String getDateTime2(String anything) {
        Date d = new Date();
        String response = Long.toString(d.getTime());
        return response;
    }
}

我尝试了为每个请求调用的缓存方法:

代码语言:javascript
复制
@org.springframework.cache.annotation.Cacheable(value="defaultCache", key="username")
public static List<Session> findSessionByUserName(String username) {

    String hql = "SELECT o FROM Session AS o WHERE o.username=:username";
    TypedQuery<Session> query = Session.entityManager().createQuery(hql, Session.class);
    query.setParameter("username", username);
    return query.getResultList();

}

..。但我受到的欢迎不是缓存的结果,而是堆栈跟踪:

代码语言:javascript
复制
java.lang.IllegalStateException: Post-processor tried to replace bean instance of type [com.ahp.core.model.Session] with (proxy) object of type [com.sun.proxy.$Proxy66] - not supported for aspect-configured classes!
    at org.springframework.beans.factory.wiring.BeanConfigurerSupport.checkExposedObject(BeanConfigurerSupport.java:168)
    at org.springframework.beans.factory.wiring.BeanConfigurerSupport.configureBean(BeanConfigurerSupport.java:140)
    at org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect.configureBean(AnnotationBeanConfigurerAspect.aj:60)
    at org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect.ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(AbstractDependencyInjectionAspect.aj:91)
    at com.ahp.core.model.Session.<init>(Session.java:20)
    at com.ahp.core.model.Session.entityManager_aroundBody0(Session.java:57)
    at com.ahp.core.model.Session.entityManager(Session.java:1)
    at com.ahp.core.processor.AccountProcessor.validateSession(AccountProcessor.java:545)
    at com.ahp.core.processor.WarehouseProcessor.consume(WarehouseProcessor.java:93)
    at com.ahp.core.processor.WarehouseProcessor.consume(WarehouseProcessor.java:1)
    at com.ahp.messaging.processor.AbstractRPCConsumer.onMessage(AbstractRPCConsumer.java:32)
    at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:228)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:756)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:679)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:82)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:167)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1241)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:660)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1005)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:989)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:82)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1103)
    at java.lang.Thread.run(Thread.java:744)

如果有用的话,下面是会话类的一个片段,它是由Spring生成的,然后使用强制重构,我去掉了所有的AspectJ,所以现在它只是一个单独的Java类:

代码语言:javascript
复制
@Entity
@Configurable
//@RooJavaBean
//@RooToString
//@RooJpaActiveRecord
public class Session {

    @PersistenceContext
    transient EntityManager entityManager;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "version")
    private Integer version;

    @ManyToOne
    private Account account;

    @ManyToOne
    private Company company;

    @Column(name = "qusername")
    private String username;

    ....

如果删除Configurable注释,实体管理器将不会被注入并引发一个IllegalStateException

代码语言:javascript
复制
    public static final EntityManager entityManager() {
        EntityManager em = new Session().entityManager;
        if (em == null)
            throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
        return em;
    }

如何使缓存在aspect-configured类上工作?

如果这是不可能的,那么让它在没有任何方面的情况下工作的过程是什么(假设这会使它不受影响)?

工作溶液

必须创建一个SessionService接口:

代码语言:javascript
复制
@RooService(domainTypes = {Session.class })
public interface SessionService {
    public List<Session> findSessionByUserName(String username);
}

SessionServiceImpl:

代码语言:javascript
复制
@Component
public class SessionServiceImpl implements SessionService {
    @Override
    @Cacheable(value="defaultCache", key="#username")
    public List<Session> findSessionByUserName(String username) {
        return Session.findSessionByUserName(username);
    }
}

必须将会话类修改为可序列化,并返回Roo注释。

代码语言:javascript
复制
@Entity
@RooJavaBean
@RooToString
@Configurable
@RooJpaActiveRecord
public class Session implements Serializable {
   ...
}

然后使用我的自动头发的SessionService:

代码语言:javascript
复制
@Autowired
SessionService sessionService;

我现在可以使用缓存:

代码语言:javascript
复制
sessionService.findSessionByUserName(...)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-20 06:47:59

问题在于,您正在尝试将缓存添加到静态方法(在Roo ActiveRecord模式中所做的方式)。您必须在bean方法(非静态)上配置缓存层。

一种方法可以是使用Roo生成在实体层和Web层之间创建服务层(查看Roo文档)。这个实用工具创建了Spring,它调用Roo实体方法并修改Contoller方法来使用它。因此,您可以用@Cacheable注释此Service的方法,以便在需要时使用缓存。

祝好运!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32110551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档