Affects: 6.1.3
A change was made in 6.1.3 to the AopUtils.getMostSpecificMethod and BridgeMethodResolver.getMostSpecificMethod that impacts how cache keys get resolved on Spring Data repositories.
In my setup, I have a repository which redefines the save(
@Repository
public interface ProfileRepository extends JpaRepository<Profile, Integer> {
@CachePut(value="ProfileRepoByCode", key="#profile.getCode()")
Profile save(Profile profile);
}
In 6.1.2, when CacheOperationMetadata.targetMethod was set, the method reference would be to the custom repository's method. In 6.1.3, this now points to the SimpleJpaRepository.save method. SimpleJpaRepository.save and I use different parameter names for the object being saved, which results in MethodBasedEvaluationContext.lazyLoadArguments no longer being able to find a match when evaluating the SpEL expression.
The attached code works when Spring Boot 3.2.1 (Framework 6.1.2) is used, but fails when upgraded to Spring Boot 3.2.2 (Framework 6.1.3).
cacheBridgeMethod-1.zip Framework_6_1_2.txt Framework_6_1_3.txt
Comment From: quaff
It should be fixed by https://github.com/spring-projects/spring-framework/pull/32089
Comment From: sdeleuze
@jhoeller Likely related to #21843.
Comment From: ykartsev
Hi guys. I've been waiting for the fix for this in 6.1.4, but after I updated to Spring Boot 3.2.3 (which has Framework of version 6.1.4) and even to 3.2.4 (Framework 6.1.5) - I'm still gettin similar error and my parameter names are not working in @Cach* annotations (@Caching, @CacheEvict, etc.), evaluating parameter as null
and as result giving the following error:
org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method getName() on null context object
My code is below:
@Transactional
@CacheEvict(value = CacheConstants.PROPERTIES_SYSTEM_CACHE_NM, key="#property.getName()")
public SystemProperty save(SystemProperty property)
{
....
}
So I'm still using workaround with parameter indexes instead of names:
@Transactional
@CacheEvict(value = CacheConstants.PROPERTIES_SYSTEM_CACHE_NM, key="#p0.getName()")
public SystemProperty save(SystemProperty property)
{
....
}
It worked fine with parameter names in Spring Boot 2.7. Please advise. Thank you in advance.
Comment From: bclozel
@ykartsev see https://github.com/spring-projects/spring-framework/issues/32547#issuecomment-2025123656
Comment From: ykartsev
Hi guys. I've been waiting for the fix for this in 6.1.4, but after I updated to Spring Boot 3.2.3 (which has Framework of version 6.1.4) and even to 3.2.4 (Framework 6.1.5) - I'm still getting similar error and my parameter names are not working in @Cach* annotations (@caching, @CacheEvict, etc.), evaluating parameter as
null
...It worked fine with parameter names in Spring Boot 2.7. Please advise. Thank you in advance.
Thanks to @HaniCera's link to another issue, I've found the answer to that in this comment by @mdeinum:
Your code needs to be compiled with -parameters to keep the parameter names, looking at your build.gradle your code isn't. This is a change in Spring 6.1 with the removal of the fallback method to determine the names of the arguments. This is also explained in the upgrade guide -> https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#parameter-name-retention
I ended up using parameter indexes instead to avoid additional build configuration, which is more error prone.
P.S.: Thanks, @bclozel , I saw your reply after posting my comment. Had this page open for 2 days :)
Comment From: ariejawinata
I also find this issue after updated to Spring Boot 3.2.0. I am using maven to compile my code. In pom.xml I use spring-boot-starter-parent which already had configuration for compiling with -parameters.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<parameters>true</parameters>
</configuration>
</plugin>
This issue rarely happens at production and cannot reproduced in testing environtment.
Please advise. Thank you in advance.
Comment From: gareth-hughes-cloudpay
Hi guys. I've been waiting for the fix for this in 6.1.4, but after I updated to Spring Boot 3.2.3 (which has Framework of version 6.1.4) and even to 3.2.4 (Framework 6.1.5) - I'm still getting similar error and my parameter names are not working in @Cach* annotations (@caching, @CacheEvict, etc.), evaluating parameter as
null
... It worked fine with parameter names in Spring Boot 2.7. Please advise. Thank you in advance.Thanks to @HaniCera's link to another issue, I've found the answer to that in this comment by @mdeinum:
Your code needs to be compiled with -parameters to keep the parameter names, looking at your build.gradle your code isn't. This is a change in Spring 6.1 with the removal of the fallback method to determine the names of the arguments. This is also explained in the upgrade guide -> https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#parameter-name-retention
I ended up using parameter indexes instead to avoid additional build configuration, which is more error prone.
P.S.: Thanks, @bclozel , I saw your reply after posting my comment. Had this page open for 2 days :)
Hi everyone.
Is there a plan to update the documentation for Spring Caching? The docs still state that the old ways of making keys will work. There is no mention of -parameters. Or is the intention for something else?
(We're grinding through upgrading a major application from 5.x to 6.0, 6.1, 6.2 and have hit the -parameters issue in multiple areas) thanks
Comment From: sbrannen
Is there a plan to update the documentation for Spring Caching? The docs still state that the old ways of making keys will work. There is no mention of -parameters. Or is the intention for something else?
@gareth-hughes-cloudpay, can you please provide links to the documentation sections in question?