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

SpelEvaluationException - retrieving and ordering from redis repository in GraalVM #564

Closed
daniel-naegele opened this issue Feb 23, 2024 · 1 comment
Assignees
Labels
theme: aot An issue related to Ahead-Of-Time processing type: bug A general bug

Comments

@daniel-naegele
Copy link

On spring-boot 3.2.3 GraalVM Java 21 when you have a repository, like:

@Repository
public interface SomeObjectRepository extends CrudRepository<SomeObject, String> {
    List<SomeObject> findAllOrderByOtherId();
}

and a redis hash class, like

@RedisHash("some-object")
public class SomeObject implements Serializable {
    @Id
    private String id;
    private int otherId;
}

I receive exceptions like this:

2024-02-23T11:11:02.763Z ERROR 1 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.spri
ngframework.expression.spel.SpelEvaluationException: EL1003E: A problem occurred whilst attempting to construct an object of type 'org.springframework.util.comparator.NullSafeComparator' using arguments '(org.springframework
.util.comparator.ComparableComparator,java.lang.Boolean)'] with root cause                                                                                                                                                      
                                                                                                                                                                                                                                
org.springframework.expression.spel.SpelEvaluationException: EL1005E: Type cannot be found 'org.springframework.util.comparator.NullSafeComparator'                                                                             
        at org.springframework.expression.spel.support.StandardTypeLocator.findType(StandardTypeLocator.java:129) ~[na:na]                                                                                                      
        at org.springframework.expression.spel.support.ReflectiveConstructorResolver.resolve(ReflectiveConstructorResolver.java:64) ~[na:na]                                                                                    
        at org.springframework.expression.spel.ast.ConstructorReference.findExecutorForConstructor(ConstructorReference.java:206) ~[na:na]                                                                                      
        at org.springframework.expression.spel.ast.ConstructorReference.createNewInstance(ConstructorReference.java:173) ~[na:na]                                                                                               
        at org.springframework.expression.spel.ast.ConstructorReference.getValueInternal(ConstructorReference.java:115) ~[na:na]                                                                                                
        at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:61) ~[na:na]                                                                                                          
        at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:97) ~[na:na]                                                                                                     
        at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:119) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:6.1.4]                                                                  
        at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:178) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:6.1.4]                                                              
        at org.springframework.data.keyvalue.core.SpelPropertyComparator.compare(SpelPropertyComparator.java:133) ~[na:na]                                                                                                      
        at java.base@21.0.2/java.util.TimSort.countRunAndMakeAscending(TimSort.java:355) ~[na:na]                                                                                                                               
        at java.base@21.0.2/java.util.TimSort.sort(TimSort.java:220) ~[na:na]                                                                                                                                                   
        at java.base@21.0.2/java.util.Arrays.sort(Arrays.java:1308) ~[na:na]                                                                                                                                                    
        at java.base@21.0.2/java.util.ArrayList.sort(ArrayList.java:1804) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:na]                                                                                                
        at org.springframework.data.redis.core.RedisQueryEngine.execute(RedisQueryEngine.java:87) ~[na:na]                                                                                                                      
        at org.springframework.data.redis.core.RedisQueryEngine.execute(RedisQueryEngine.java:59) ~[na:na]                                                                                                                      
        at org.springframework.data.keyvalue.core.QueryEngine.execute(QueryEngine.java:73) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                                                            
        at org.springframework.data.keyvalue.core.AbstractKeyValueAdapter.find(AbstractKeyValueAdapter.java:75) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                                       
        at org.springframework.data.keyvalue.core.KeyValueTemplate.lambda$find$6(KeyValueTemplate.java:343) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                                           
        at org.springframework.data.keyvalue.core.KeyValueTemplate.execute(KeyValueTemplate.java:314) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                                                 
        at org.springframework.data.keyvalue.core.KeyValueTemplate.executeRequired(KeyValueTemplate.java:329) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                                         
        at org.springframework.data.keyvalue.core.KeyValueTemplate.find(KeyValueTemplate.java:341) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                                                    
        at org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery.doExecute(KeyValuePartTreeQuery.java:136) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                         
        at org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery.execute(KeyValuePartTreeQuery.java:111) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                           
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                        
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:3.2.3]                                          
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164) ~[na:na]                                                                           
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143) ~[na:na]                                                                             
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:6.1.4]                                                  
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[na:na]                                                                                                 
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:6.1.4]                                                  
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220) ~[na:na]                                                                                                                    
        at jdk.proxy4/jdk.proxy4.$Proxy58.findAllByRadioOrderByAudioconId(Unknown Source) ~[na:na]                                                                                                                              
        at java.base@21.0.2/java.lang.reflect.Method.invoke(Method.java:580) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:na]                                                                                             
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351) ~[na:na]                                                                                                                  
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:6.1.4]                                          
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:6.1.4]                                                  
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[na:na]                                                                      
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[de.radiohost.nxtradio.NxtRadioServiceApplication:6.1.4]                                                  
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220) ~[na:na]                                                                                                                    
        at jdk.proxy4/jdk.proxy4.$Proxy58.findAllOrderByOtherId(Unknown Source) ~[na:na]                                                                                                                              

I had to register reflection for ComparableComparator.class, NullSafeComparator.class and Comparator.class (Constructors and Methods) to use the findAllOrderByOtherId method.

@christophstrobl christophstrobl self-assigned this Feb 23, 2024
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Feb 23, 2024
@christophstrobl christophstrobl added type: bug A general bug theme: aot An issue related to Ahead-Of-Time processing and removed status: waiting-for-triage An issue we've not yet triaged labels Feb 23, 2024
@christophstrobl
Copy link
Member

Thank you @daniel-naegele for reporting the issue. We'll take care of this.

@christophstrobl christophstrobl added this to the 3.1.10 (2023.0.10) milestone Feb 23, 2024
@mp911de mp911de transferred this issue from spring-projects/spring-data-redis Mar 4, 2024
christophstrobl added a commit that referenced this issue Mar 15, 2024
We now use a dedicated instance instead of relying upon reflectively created ones, however we still need to register the compare call for reflective access.

Resolves: #564
christophstrobl added a commit that referenced this issue Mar 15, 2024
We now use a dedicated instance instead of relying upon reflectively created ones, however we still need to register the compare call for reflective access.

Resolves: #564
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: aot An issue related to Ahead-Of-Time processing type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants