Spring Data JPA:修改过的实体在没有@CachePut的情况下在EhCache中进行更新

时间:2014-07-22 19:55:36

标签: spring ehcache spring-data-jpa spring-3

我正在使用:

  • Spring Framework 4.0.5
  • Spring Data JPA 1.6.0.RELEASE
  • EhCache 2.8.3

我有以下ProductServiceImpl方法:

@Override
@Cacheable(value="products", key="#product.id")
public Product save(Product product) {
    return this.productRepository.save(product);
}

@Override
@Cacheable(value="products", key="#id")
public Product findOne(Integer id) {
    return this.productRepository.findOne(id);
}

@Override
@CachePut(value="products", key="#product.id")
public Product update(Product product) {
    return this.productRepository.save(product);
}

我有一个id为2的产品保存在DB(HSQL)中,库存为1。 根据上面显示的三种方法,必须相同, 2 通过key="#id"key="#product.id"

现在,我知道缓存的工作方式如下,如何一个HashMap。

HashMap products = new HashMap();
products.put(2, product02);

Main 类中,我有以下内容(我正在使用注释让您了解我的逻辑):

logger.info("Inserting product02");
// must save the product02 in the cache too
userExecutionService01.executeSaveProduct(product02); 
…
logger.info("-----------------");

logger.info("Getting product02");
product02 = null;
//Must retrieve the object from the cache, it has been already saved. 
//The Stock must be 1.
product02 = userExecutionService01.executeFindProduct(2);
logger.info("Stock {}:", product02.getStock());

//1 + 100 = 101
product02.setStock(product02.getStock().add(new BigDecimal("100.00")));
//Must update database and the cache with the same product with the new Stock 101.
userExecutionService01.executeUpdateProduct(product02, false);

//Must retrieve the object from the cache, it has been already updated. 
//The Stock must be 101.
logger.info("Getting & Printing product02");
userExecutionService01.executePrintProduct(2);

executeFindProduct 方法有

@Override
public Product executeFindProduct(Integer id){
    return this.productService.findOne(id);             
}

executeUpdateProduct 方法

@Override
public void executeUpdateProduct(Product product, boolean throwException){      
    logger.info("+++ executeUpdateProduct - start ");
    logger.info("   Alfa: {}", this.productService.findOne(product.getId()).getStock());
    this.productService.update(product);
    logger.info("   Beta: {}", this.productService.findOne(product.getId()).getStock());
    logger.info("+++ executeUpdateProduct - end ");
}

使用AOP,如果Cache正在运行,我正在进行控制。

@Before("execution(* *..ProductService.*(..))")
public void beforeServiceLogging(JoinPoint jointPoint){
    logger.info(">Before {} called", jointPoint.getSignature().getName());
}

@Before("execution(* *..ProductRepository.*(..))")
public void beforeRepositoryLogging(JoinPoint jointPoint){
    logger.info(">>Before {} called", jointPoint.getSignature().getName());
}
来自服务的

>和来自存储库的>>

该应用有关于缓存的意外行为

如果我使用:

@Override
@Cacheable(value="products", key="#id")
public Product findOne(Integer id) {
    return this.productRepository.findOne(id);
}

结果输出显示

- Inserting product02
- >Before save called
- >>Before save called  //repository has been called, then: saved in DB and Cache
...
- -----------------
- Getting product02
- >Before findOne called
- Stock 1: //Correct, cache returns the expected value (1)
- +++ executeUpdateProduct - start 
- >Before findOne called
-    Alfa: 101.00 //Wrong, data has not been neither updated in the DB nor @Cacheput has been executed
- >Before update called
- >>Before save called //Repository, just then DB and Cache are being updated
- >Before findOne called
-    Beta: 101.00
- +++ executeUpdateProduct - end 
- Getting & Printing product02
- >Before findOne called
- Product [id=2, ... stock=101.00, …]

我很困惑,为什么" alfa"用库存101显示对象? 尚未调用Db,当然@Cacheput尚未执行。

是的,我知道我有这句话: product02.setStock(product02.getStock().add(new BigDecimal("100.00"))); 但是没有任何意义,线路以某种方式更新缓存,因为我使用显式 @CachePut

我只知道:EntityManager应该知道该product02的更新,并等到存储库执行更新/保存方法。

如果我使用

@Override
//@Cacheable(value="products", key="#id")
public Product findOne(Integer id) {
    return this.productRepository.findOne(id);
}

所有关于阿尔法的都很好。

发生了什么事?

0 个答案:

没有答案