2013-01-07 41 views
5

को लागू करते समय (त्रुटि "अशक्त कुंजी कैश ऑपरेशन के लिए लौट आए"), मैं वसंत कैश अमूर्त वी.एस. इंटरफेस के साथ एक समस्या भर में आया था। चलें कहते हैं कि मैं निम्नलिखित इंटरफेस है:स्प्रिंग कैश अमूर्त वी.एस. इंटरफेस वी.एस. कुंजी परम

package com.example.cache; 

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

और दो निम्नलिखित कार्यान्वयन:

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); 
    } 
} 

ध्यान दें कि IAddItMethod एक @Cacheable निर्दिष्ट नहीं है। हम @Cacheable एनोटेशन के बिना अन्य कार्यान्वयन (पूर्व विधि ImplThree) हो सकता है।

हम साथ एक सरल beans.xml मिल गया है: कि को जोड़ना

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

, दो 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)); 
    } 

} 

जब मैं व्यक्तिगत रूप से परीक्षण चलाता हूं, तो वे सफल होते हैं। हालांकि, अगर मैं उन दोनों को एक साथ चलाने के (पैकेज का चयन, राइट-क्लिक करें के रूप में चलाने), दूसरा एक (जरूरी नहीं MethodImplTwoTest, बस एक दूसरे के चल रहा है) निम्न अपवादों के साथ असफल हो जायेगी:

 
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) 

नोट: मैं ग्रहण एसटीएस 3.0 का उपयोग कर रहा हूं और "जेनरेट क्लास फाइलों में परिवर्तनीय विशेषताओं को जोड़ें" सक्षम है।

महत्वपूर्ण: मैं "कुंजी" @Cacheable एनोटेशन में निर्दिष्ट नहीं करते हैं, यह काम करता है।

क्या कुछ भी मैं निर्दिष्ट करना भूल गया? config? एनोटेशन?

अग्रिम धन्यवाद!

उत्तर

4

मेरा अनुमान है तो यह कुंजी और नहीं keyTwo है कि JDK प्रॉक्सी के लिए पैरामीटर नाम इंटरफेस विधि से लाई गई है।

अद्यतन: आप पैरामीटर अनुक्रमणिका उपयोग करने के लिए कोशिश कर सकते हैं बजाय

किसी कारण से नाम उपलब्ध (पूर्व: कोई डिबग जानकारी) नहीं हैं, तो पैरामीटर नाम भी पी < के अंतर्गत उपलब्ध हैं #arg> जहां #arg पैरामीटर इंडेक्स (0 से शुरू) के लिए खड़ा है।

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

+0

देखना यह धन्यवाद काम करता है! हालांकि, मैं इसे प्रतिबंधित मानता हूं और इसका सम्मान करने के लिए कार्यान्वयन को लागू करना जटिल है। मैं इंटरफ़ेस और वर्तमान कार्यान्वयन में पूर्ण जावाडोक जोड़ूंगा लेकिन एक अन्य डेवलपर एक नए कार्यान्वयन के लिए एक ही समस्या पर ठोकर खा सकता है। फिर से धन्यवाद Boris! – dostiguy

+0

@dostiguy मैंने इंडेक्स द्वारा पैरामीटर तक पहुंचने के दस्तावेज के लिए एक लिंक जोड़ा, मैंने इसे आजमाया नहीं है हालांकि –

+0

अच्छी सोच है, मैं भूल गया था कि हम ऐसा कर सकते हैं।मैंने कोशिश की और मेरे परीक्षण चलाए (असली कार्यान्वयन में लगभग 100 टेस्ट केस हैं, और चाबियाँ उदाहरण की तुलना में अधिक जटिल हैं) और यह काम करती है। अब मुझे यकीन नहीं है कि मैं किस तरह से पसंद करता हूं। एक बार फिर धन्यवाद। – dostiguy