Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Cache Abstraction annotations do not trigger CQ [DATAGEODE-50] #70

Closed
spring-projects-issues opened this issue Oct 17, 2017 · 1 comment
Assignees
Labels
in: cq type: bug

Comments

@spring-projects-issues
Copy link

@spring-projects-issues spring-projects-issues commented Oct 17, 2017

John Blum opened DATAGEODE-50 and commented

When implementing a CQ, it does not trigger when a method is annotated with @Cachable or @CachePut. However, a CQ is triggered when a method is annotated with @CacheEvict. This should be consistent and a @Cachable or @CachePut annotated service method should trigger a CQ.

Sample code can be found here:

https://github.com/pivotal-Jammy-Louie/PCC-Pizza

Scenario:

  • Created a Region called "PizzaOrder"
  • Created a CQ Query: "SELECT * FROM /PizzaOrder"
  • The CQ Listener/handler just performs a System.out.println(..) to indicate to me that it has been triggered.
  • I use the following in my service:
    @Cacheable(value = "PizzaOrder")
    public PizzaOrder getPizzaOrder(long pizzaOrderId){
        this.simulateSlowService();
        return this.pizzaOrderRepository.findById(pizzaOrderId).orElse(null);
    }

    @CachePut(value = "PizzaOrder")
    public PizzaOrder createOrder (long customerId, long pizzaId){
        Customer customer = this.customerRepository.findById(customerId).orElse(null);
        Pizza pizza = this.pizzaRepository.findById(pizzaId).get();
        PizzaOrder order = new PizzaOrder(customer, pizza);
        return this.pizzaOrderRepository.save(order);
    }

    @CacheEvict(value = "PizzaOrder")
    public PizzaOrder completePizzaOrder(long pizzaOrderId){
        PizzaOrder pizzaOrder = this.pizzaOrderGemfireRepository.findById(pizzaOrderId).orElseGet(()->this.getPizzaOrder(pizzaOrderId));
        pizzaOrder.setOrderComplete(true);
        return this.pizzaOrderRepository.save(pizzaOrder);
    }

When the method completePizzaOrder is invoked I can see that the CQ is triggered but the other annotations do not trigger the CQ.

If I perform a put through GFSH I can see the CQ trigger.


Affects: 2.0 GA (Kay)

Referenced from: commits a46f1cc, d98c4af

Backported to: 2.0.1 (Kay SR1)

@spring-projects-issues
Copy link
Author

@spring-projects-issues spring-projects-issues commented Oct 23, 2017

John Blum commented

I think in this case, triggering of the CQ(s) from Spring Cache annotated service methods may have been all or nothing. Meaning, if a @CacheEvict annotated service method caused a CQ to be triggered, then it is likely the @Cacheable and @CachePut annotations would also cause the same CQ to be triggered.

However, there did exist 2 bugs in the code that would potentially cause a CQ to not be registered properly.

  1. The first bug involved identifying and registering CQs before the initialization of the underlying ContinuousQueryListenerContainer relative to the beans that contain @ContinuousQuery annotated callback methods (CQs). This code path leads to adding a listener to the container for the CQ callback, which creates the CQ and stores a reference for execution later, which is after the container has been initialized. However, the container will go onto clear/close all existing CQs during initialization, prior to execution. This results in having no CQs to execute.

  2. The second bug identified involves declaring a CQ (using the @ContinuousQuery annotation) on the same bean that may also be proxied by Spring for other purposes (e.g. Caching, Security or even Transaction Management). Here is 1 example where a CQ is declared on a bean that will also be proxied for caching purposes (given the presence of the Spring Caching Annotations, e.g. @Cacheable). In this case, the CQ cannot be identified since what is passed to the Spring BeanPostProcessor used to inspect and identify CQs is a "PROXY" object and not the actual bean instance declared and registered with the container. As such, the CQ never gets registered and therefore will never be triggered

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: cq type: bug
Projects
None yet
Development

No branches or pull requests

2 participants