When a custom class is annotated with @Repository
annotation and Spring Data JPA is on the classpath (I believe it will happen with other spring data modules present too), package private methods from the annotated class (that get turned into proxy) are not visible in AdvisedSupport
:
Sample class:
@Repository
public class CreditCardRepository {
private final JdbcTemplate jdbcTemplate;
public CreditCardRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
Optional<CreditCard> findByCardNumber(String cardNumber) {
...
}
Calling findByCardNumber
results in:
java.lang.NullPointerException: null
at org.springframework.aop.framework.AdvisedSupport$MethodCacheKey.<init>(AdvisedSupport.java:578) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
at org.springframework.aop.framework.AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice(AdvisedSupport.java:470) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) ~[na:na]
at com.sivalabs.bookstore.payments.domain.CreditCardRepository$$SpringCGLIB$$0.findByCardNumber(<generated>) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:na]
at com.sivalabs.bookstore.payments.domain.PaymentService.validate(PaymentService.java:21) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:na]
at java.base@17.0.5/java.lang.reflect.Method.invoke(Method.java:568) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[na:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:752) ~[na:na]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[na:na]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:752) ~[na:na]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703) ~[na:na]
at com.sivalabs.bookstore.payments.domain.PaymentService$$SpringCGLIB$$0.validate(<generated>) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:na]
at com.sivalabs.bookstore.payments.api.PaymentController.validate(PaymentController.java:23) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:na]
at java.base@17.0.5/java.lang.reflect.Method.invoke(Method.java:568) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[com.sivalabs.bookstore.payments.PaymentServiceApplication:6.0.3]
Repo reproducing this issue made by @sivaprasadreddy https://github.com/siva-throwaway-work/spring-boot-native-issue
Current workaround:
- change method visibility to
public
- instead of
@Repository
use@Component
annotation on the custom repository class
I think it could be related to https://github.com/spring-projects/spring-framework/issues/29309 but after 2h of try & error with registering custom hints i give up
Comment From: mdeinum
Did a little test, the same happens without spring-data-jpa
and only the @Repository
annotation. It appears as if the proxy created for the exception translation is the culprit.
Comment From: sdeleuze
The exception looks similar to #29582.