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

Parameter based cache keys on repository methods can't resolve after 6.1.2->6.1.3 #32087

Closed
eryanv opened this issue Jan 23, 2024 · 6 comments
Closed
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Milestone

Comments

@eryanv
Copy link

eryanv commented Jan 23, 2024

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() method, so that I can put a @CachePut annotation on top. The key for this particular cache is defined using the method's parameter.

@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

@quaff
Copy link
Contributor

quaff commented Jan 23, 2024

It should be fixed by #32089

@sdeleuze
Copy link
Contributor

@jhoeller Likely related to #21843.

@jhoeller jhoeller self-assigned this Jan 23, 2024
@jhoeller jhoeller added type: regression A bug that is also a regression in: core Issues in core modules (aop, beans, core, context, expression) and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 23, 2024
@jhoeller jhoeller added this to the 6.1.4 milestone Jan 23, 2024
@ykartsev
Copy link

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.

@bclozel
Copy link
Member

bclozel commented Apr 4, 2024

@ykartsev see #32547 (comment)

@ykartsev
Copy link

ykartsev commented Apr 4, 2024

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 :)

@ariejawinata
Copy link

ariejawinata commented Jun 12, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Projects
None yet
8 participants