2015-10-01 94 views
1

我使用spring-data-jpa 1.9.0.RELEASE並希望在我的存儲庫中使用彈簧緩存機制,例如,春季緩存抽象(AdviceMode.ASPECTJ)不工作在spring-data-jpa存儲庫內

public interface LandDao extends CrudRepository<Land, Long> { 

    @Cacheable("laender") 
    Land findByName(String land) 
} 

這裏是我的緩存配置:

@Configuration 
@EnableCaching(mode=AdviceMode.ASPECTJ) 
public class EhCacheConfiguration extends CachingConfigurerSupport { 
... 

請注意,我用AdviceMode.ASPECTJ(編譯時織入)。不幸的是,調用repo方法'findByName'時,緩存不起作用。 更改緩存模式爲AdviceMode.PROXY一切正常。

爲了確保在原則上緩存的工作和AspectJ,我寫了下面的服務:

@Service 
public class LandService { 

    @Autowired 
    LandDao landDao; 

    @Cacheable("landCache") 
    public Land getLand(String bez) { 
    return landDao.findByName(bez); 
    } 
} 

在這種情況下,高速緩存就像一個魅力。所以我認爲我的應用程序的所有部分都配置正確,問題在於spring-data-jpa和AspectJ緩存模式的結合。有沒有人知道這裏有什麼問題?

回答

2

好的,自己找到了我的問題的答案。負責方面org.springframework.cache.aspectj.AnnotationCacheAspect的javadoc中說:

當使用這個方面,你必須註解這個實現類(和/或這個類中的方法),而不是接口(如果有的話)該類實現。 AspectJ遵循Java的規則,即接口上的註釋不會被繼承。

所以無法在repository接口中使用@Cacheable註釋和aspectj。我的解決方案現在是利用custom implementations for Spring Data repositories

界面自定義存儲庫功能:

public interface LandRepositoryCustom { 

    Land findByNameCached(String land); 
} 

使用的定製庫功能實現查詢DSL:

@Repository 
public class LandRepositoryImpl extends QueryDslRepositorySupport 
     implements LandRepositoryCustom { 

    @Override 
    @Cacheable("landCache") 
    public Land findByNameCached(String land) { 
    return from(QLand.land).where(QLand.land.name.eq(land)).singleResult(QLand.land); 
    } 
} 

注爲的@Cacheable註釋findByNameCached方法。

基本庫界面:

public interface LandRepository extends CrudRepository<Land, Long>, LandRepositoryCustom { 
} 

使用存儲庫:

public class SomeService { 

    @Autowired 
    LandRepository landDao; 

    public void foo() { 
    // Cache is working here:-) 
    Land land = landDao.findByNameCached("Germany"); 
    } 
} 

這將是有益的補充與此限制在春天的數據參考的說明。

+0

不幸的是,如果您希望在保存實體時逐出緩存,則我的解決方案無法工作,請參閱@ oliver-gierke的[this](http://stackoverflow.com/a/26283080/5396465)發佈。這是因爲我們無法使用CacheEvict註釋註釋CrudRepository接口的方法 S save(S實體)。我想這個問題不能輕易解決... – smitzkus