0

To call a method I use a hashmap with Lambda Expressions to find out which method should be called to lookup data. The problem is: if I call this method directly - the cache is working without any problem. But if I get this method from a map - no cache it all. Is there a possibility to fix it or Spring Cache can not be used for such scenario?

@Component
@Scope("singleton")
@SuppressWarnings("SpringJavaAutowiringInspection")
public class RulesZ
{
    // Lookup is marked as @FunctionalInterface
    Map<String,Lookup> lookups; 

    @Autowired
    LookupZMapper lookzMapper;

    @PostConstruct
    public void init()
    {
        lookups = new LinkedHashMap<String,Lookup>();
        lookups.put("shortform",(String kur, String type,String typeAddition)->  getKurForm(kur,type,typeAddition));
    }

@Cacheable(value="lookupKur")
    public String getKurForm(String kur, String type, String typeAddition)
    {
        LookupZtExample ex = new LookupZExample();
        ex.createCriteria()...;
        List res = lookzMapper.selectByExample(ex);
...
return "found value";
    }

That means: if I call the method getKurForm directly - it will be cached, but if I call it using:

RulesZ.getLookups().get("shortform").lookup("val1","DF","DS"));

Than it will search in a DB for every method call.

Matteo
  • 21
  • 2
  • @chrylis: I’m not sure whether it is obvious to everyone that a lambda expression is an invocation from the same class. And I don’t know what would happen when using a method reference instead. Thus, it’s not an exact duplicate as the other question doesn’t deal with lambda expressions… – Holger Dec 17 '15 at 11:42
  • @Holger A lambda is syntactic sugar for an anonymous inner class, which will invoke local method calls directly on the containing `this`. Any inner class would display the exact same behavior; there's nothing lambda-specific about it. – chrylis -cautiouslyoptimistic- Dec 17 '15 at 11:55
  • 1
    @chrylis: if that were true, the issue wasn’t there as an inner class is a *different* class, so if you put the code of the lambda expression into an inner class, the call is *not* made from the same class. The important point here is that the lambda expression is desugared into a synthetic *method* in the same class and *that* method will get called by the generated class. Since that doesn’t happen with method references (usually), there, the caller is a different class but the question is whether AspectJ will instrument the generated anonymous class. Does it still sound all obvious to you? – Holger Dec 17 '15 at 12:04
  • @Holger AspectJ isn't involved; this is Spring proxy AOP. If you put Spring in AspectJ mode, this should work. – chrylis -cautiouslyoptimistic- Dec 17 '15 at 12:35
  • Interesting discussion and thanks for the hint, @chrylis. I have made a new bean which perform a DB search and call the method bean via wrapper. It's not a big deal as I need this wrapper anyway (the sample code was simplified, I have more parameter). This approach works, so, my records were cached. – Matteo Dec 17 '15 at 13:21

0 Answers0