问题
I'm developing Spring Boot + Redis
example. In this example, I've developed some custom methods which pull details based on RoleName. For the below method userRepository.findByRole_RoleName("ADMIN")
or userRepository.findByMiddleNameContaining("Li");
, we're getting the below exception.
The reference URL: https://docs.spring.io/spring-data/keyvalue/docs/1.2.15.RELEASE/reference/html/
Could anyone please provider pointers ? All the other methods are working fine. But just this method causing the problems. I will post all the required code below for reference.
Error:
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230)
at com.baeldung.MainAppDemo.main(MainAppDemo.java:21)
Caused by: java.lang.IllegalArgumentException: CONTAINING (1): [IsContaining, Containing, Contains]is not supported for redis query derivation
at org.springframework.data.redis.repository.query.RedisQueryCreator.from(RedisQueryCreator.java:67)
at org.springframework.data.redis.repository.query.RedisQueryCreator.create(RedisQueryCreator.java:53)
at org.springframework.data.redis.repository.query.RedisQueryCreator.create(RedisQueryCreator.java:41)
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:119)
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95)
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:81)
at org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery.createQuery(KeyValuePartTreeQuery.java:211)
at org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery.prepareQuery(KeyValuePartTreeQuery.java:148)
at org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery.execute(KeyValuePartTreeQuery.java:106)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:602)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:590)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy65.findByMiddleNameContains(Unknown Source)
at com.baeldung.MainAppDemo.run(MainAppDemo.java:38)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:792)
... 5 common frames omitted
2018-11-04 00:27:29,639 INFO [main] org.springframework.context.support.AbstractApplicationContext: Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6f96c77: startup date [Sun Nov 04 00:27:26 IST 2018]; root of context hierarchy
2018-11-04 00:27:29,645 INFO [main] org.springframework.jmx.export.MBeanExporter: Unregistering JMX-exposed beans on shutdown
User.java
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@RedisHash("user")
public class User {
private @Id String id;
private @Indexed String firstName;
private @Indexed String middleName;
private @Indexed String lastName;
private Role role;
}
Role.java
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@RedisHash("Role")
public class Role {
private @Id String id;
private @Indexed String roleName;
}
UserRepository.java
public interface UserRepository extends CrudRepository<User, String>{
List<User> findByFirstNameAndLastName(String firstName, String lastName);
List<User> findByMiddleNameContains(String firstName);
List<User> findByRole_RoleName(String roleName);
}
MainAppDemo.java
@SpringBootApplication
public class MainAppDemo implements CommandLineRunner{
@Autowired
private UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(MainAppDemo.class, args);
}
@Override
public void run(String... args) throws Exception {
Role role1 = Role.builder().id("R1").roleName("ADMIN").build();
User user1 = User.builder().firstName("Matt").middleName("Mike").lastName("Wixson").role(role1).build();
Role role2 = Role.builder().id("R2").roleName("API").build();
User user2 = User.builder().firstName("John").middleName("Lima").lastName("Kerr").role(role2).build();
userRepository.save(user1);
userRepository.save(user2);
List<User> u = userRepository.findByFirstNameAndLastName("Matt", "Wixson");
System.out.println("Find By First Name and Last Name = "+u.toString());
List<User> u2 = userRepository.findByMiddleNameContains("Li");
System.out.println("Contains ="+u2);
List<User> adminUser = userRepository.findByRole_RoleName("ADMIN");
System.out.println("ADMIN USER ="+adminUser);
}
}
JIRA defect: https://jira.spring.io/browse/DATAREDIS-887
UPDATE:
I developed the query like this and calling from the main method, still I am getting the same error. Please suggest working solution.
@Query("SELECT u FROM User u WHERE u.middleName LIKE :middleName ")
List<User> findByMiddleNameContaining(@Param("middleName") String middleName);
回答1:
Ok lets start from "How Redis Work"
Redis work on Hashes for ID which helps in faster location of record. @Indexed is also hashed and stored for faster pin-pointing the record
So By Default for MiddleName the "contain" query will not work as Hash for "Test" string will not be contained in Hash for String "TestUser".
But ExampleMatcher is here to the rescue.
Source: https://docs.spring.io/spring-data/redis/docs/2.1.2.RELEASE/reference/html/#query-by-example
Solution for RoleName search on Role Object is relatively simple: Use this query
userRepository.findByRoleRoleName("ADMIN") (Basically remove the underscore)
And good news is that it can be combined with the above ExampleMatcher.
Let's discuss if you have doubt.
Helpfull Reference for RoleName search : Query Nested Objects in Redis using Spring Data
回答2:
On Redis with Spring Boot you just have some queries for finder that are supported like Is, Equals, combine with And, Or , you can take a look on Table 9:
https://docs.spring.io/spring-data/redis/docs/current/reference/html/#redis.repositories.queries
UPDATED
You can create a query following this documentation link as reference
https://docs.spring.io/spring-data/redis/docs/2.1.2.RELEASE/reference/html/#query-by-example
来源:https://stackoverflow.com/questions/53134556/caused-by-java-lang-illegalargumentexception-containing-1-iscontaining-co