2013-01-07 19 views
5

Trong khi triển khai, tôi đã gặp một vấn đề với giao diện Spring Cache Abstraction VS. phép nói rằng tôi có giao diện sau:Tóm tắt bộ đệm mùa xuân VS giao diện VS khóa param (lỗi "Null key return for cache operation")

package com.example.cache; 

public interface IAddItMethod 
{ 
    Integer addIt(String key); 
} 

Và hai ngôn ngữ này như sau:

package com.example.cache; 

import org.springframework.cache.annotation.Cacheable; 
import org.springframework.stereotype.Component; 

@Component 
public class MethodImplOne implements IAddItMethod 
{ 
    @Override 
    @Cacheable(value="integersPlusOne", key="#keyOne") 
    public Integer addIt(String keyOne) 
    { 
     return new Integer(Integer.parseInt(keyOne) + 1); 
    } 
} 

.

package com.example.cache; 

import org.springframework.cache.annotation.Cacheable; 
import org.springframework.stereotype.Component; 

@Component 
public class MethodImplTwo implements IAddItMethod 
{ 
    @Override 
    @Cacheable(value="integersPlusTwo", key="#keyTwo") 
    public Integer addIt(String keyTwo) 
    { 
     return new Integer(Integer.parseInt(keyTwo) + 2); 
    } 
} 

Lưu ý rằng IAddItMethod không phải là chỉ định @Cacheable. Chúng tôi có thể có triển khai khác (ví dụ: MethodImplThree) mà không có chú thích @Cacheable.

Chúng tôi đã có một beans.xml đơn giản với:

context:component-scan base-package="com.example.cache" 

Thêm vào đó, hai trường hợp thử nghiệm JUnit:

package com.example.cache; 

import static org.junit.Assert.assertEquals; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:beans.xml"}) 
public class MethodImplOneTest 
{ 

    @Autowired 
    @Qualifier("methodImplOne") 
    private IAddItMethod classUnderTest; 

    @Test 
    public void testInit() 
    { 
     int number = 1; 
     assertEquals(new Integer(number + 1), classUnderTest.addIt("" + number)); 
    } 

} 

.

package com.example.cache; 

import static org.junit.Assert.assertEquals; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:beans.xml"}) 
public class MethodImplTwoTest 
{ 

    @Autowired 
    @Qualifier("methodImplTwo") 
    private IAddItMethod classUnderTest; 

    @Test 
    public void testInit() 
    { 
     int number = 1; 
     assertEquals(new Integer(number + 2), classUnderTest.addIt("" + number)); 
    } 

} 

Khi tôi chạy thử nghiệm riêng lẻ, chúng thành công. Tuy nhiên, nếu tôi chạy chúng cả hai cùng nhau (chọn gói, nhấp chuột phải, chạy như), điều thứ hai (không nhất thiết phải MethodImplTwoTest, chỉ là thứ hai chạy) sẽ thất bại với các ngoại lệ sau đây:

 
java.lang.IllegalArgumentException: Null key returned for cache operation (maybe you are using named params on classes without debug info?) CacheableOperation[public java.lang.Integer com.example.cache.MethodImplOne.addIt(java.lang.String)] caches=[integersPlusOne] | condition='' | key='#keyOne' 
    at org.springframework.cache.interceptor.CacheAspectSupport.inspectCacheables(CacheAspectSupport.java:297) 
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:198) 
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:66) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
    at $Proxy16.addIt(Unknown Source) 
    at com.example.cache.ITMethodImplOneIntegrationTest.testInit(ITMethodImplOneIntegrationTest.java:26) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) 
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

lưu ý: Tôi đang sử dụng Eclipse STS 3.0 và "Thêm thuộc tính biến cho tệp lớp được tạo" được bật.

QUAN TRỌNG: Nếu tôi không chỉ định "khóa" trong chú thích @Cacheable, nó hoạt động.

Có điều gì tôi quên chỉ định không? config? chú thích?

Cảm ơn trước!

Trả lời

4

Đoán của tôi là đối với proxy jdk, tên thông số được lấy từ phương thức giao diện để khóa và không phải keyTwo.

cập nhật: Bạn có thể cố gắng sử dụng các chỉ số tham số thay vì

Nếu vì một lý do nào tên là không có sẵn (ví dụ: không có thông tin debug ), tên tham số cũng có sẵn dưới p < #arg> trong đó #arg là viết tắt của chỉ số tham số (bắt đầu từ 0).

thấy http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html#cache-spel-context

+0

Nó hoạt động nhờ! Tuy nhiên, tôi coi đây là hạn chế và rất phức tạp để thực thi các triển khai để tôn trọng điều đó. Tôi sẽ thêm javadoc hoàn chỉnh vào giao diện và các triển khai hiện tại nhưng một nhà phát triển khác có thể vấp phải cùng một vấn đề cho một triển khai mới. Cảm ơn một lần nữa Boris! – dostiguy

+0

@dostiguy Tôi đã thêm một liên kết đến tài liệu liên quan đến việc truy cập các tham số theo chỉ mục, tôi đã không thử bản thân mình mặc dù –

+0

Suy nghĩ tốt, tôi đã quên chúng tôi có thể làm điều đó.Tôi đã thử nó và chạy thử nghiệm của tôi (thực hiện thực tế có khoảng 100 trường hợp thử nghiệm, và các phím phức tạp hơn ví dụ) và nó hoạt động. Bây giờ tôi không chắc mình thích cách nào hơn. Cảm ơn một lần nữa. – dostiguy

Các vấn đề liên quan