引起:java.lang.IllegalArgumentException: CONTAINING (1): [IsContaining, Containing, Contains]不支持redis查
Posted
技术标签:
【中文标题】引起:java.lang.IllegalArgumentException: CONTAINING (1): [IsContaining, Containing, Contains]不支持redis查询派生-Redis【英文标题】:Caused by: java.lang.IllegalArgumentException: CONTAINING (1): [IsContaining, Containing, Contains]is not supported for redis query derivation - Redis 【发布时间】:2019-04-07 15:24:03 【问题描述】:我正在开发Spring Boot + Redis
示例。在此示例中,我开发了一些基于 RoleName 提取详细信息的自定义方法。对于下面的方法userRepository.findByRole_RoleName("ADMIN")
或userRepository.findByMiddleNameContaining("Li");
,我们得到了下面的异常。
参考网址:https://docs.spring.io/spring-data/keyvalue/docs/1.2.15.RELEASE/reference/html/
任何人都可以请提供者指点吗?所有其他方法都工作正常。但正是这种方法导致了问题。我将在下面发布所有必需的代码以供参考。
错误:
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 缺陷:https://jira.spring.io/browse/DATAREDIS-887
更新:
我开发了这样的查询并从 main 方法调用,但我仍然遇到同样的错误。请提出可行的解决方案。
@Query("SELECT u FROM User u WHERE u.middleName LIKE :middleName ")
List<User> findByMiddleNameContaining(@Param("middleName") String middleName);
【问题讨论】:
【参考方案1】:好的,让我们从“Redis 的工作原理”开始
Redis 处理 ID 哈希,这有助于更快地定位记录。 @Indexed 也被散列和存储,以便更快地定位记录
因此默认情况下,对于 MiddleName,“包含”查询将不起作用,因为“测试”字符串的哈希不会包含在字符串“TestUser”的哈希中。
但是 ExampleMatcher 可以帮上忙。
来源:https://docs.spring.io/spring-data/redis/docs/2.1.2.RELEASE/reference/html/#query-by-example
角色对象上的角色名称搜索解决方案比较简单:使用这个查询
userRepository.findByRoleRoleName("ADMIN") (基本去掉下划线)
好消息是它可以与上面的 ExampleMatcher 结合使用。
如果您有疑问,我们来讨论。
角色名称搜索的帮助参考:Query Nested Objects in Redis using Spring Data
【讨论】:
【参考方案2】:在带有 Spring Boot 的 Redis 上,您只有一些支持的 finder 查询,例如 Is、Equals、与 And、Or 结合,您可以查看表 9:
https://docs.spring.io/spring-data/redis/docs/current/reference/html/#redis.repositories.queries
更新
您可以在此文档链接之后创建一个查询作为参考
https://docs.spring.io/spring-data/redis/docs/2.1.2.RELEASE/reference/html/#query-by-example
【讨论】:
除了使用 Spring Data Redis,还有其他解决方案吗?像 Jeddision 或 radision 一样可以让我执行一些复杂的查询? 可以创建自定义查询,这里有参考***.com/questions/42966967/… @Jonathan Johx - 查询注释纯粹是 JPA 的一部分。所以你是说我们应该使用 JPA API 与 Redis 对话,以防从自定义查询中获取数据? @ Jonathan Johx - 请参阅更新,我创建了自定义查询,仍然给出相同的错误。 对不起,我错了 xD 呵呵……我回答了很多问题……真的很抱歉。以上是关于引起:java.lang.IllegalArgumentException: CONTAINING (1): [IsContaining, Containing, Contains]不支持redis查的主要内容,如果未能解决你的问题,请参考以下文章