我有一个java对象,我存储在redis商店中。
@RedisHash("UserProfile")
public class UserProfile implements Serializable {
@Id String id;
@Reference PersonalInfo personalInfo = new PersonalInfo();
@Reference BusinessInfo businessInfo = new BusinessInfo();
...
}
现在,PersonalInfo
对象的结构为:
public class PersonalInfo {
private String firstName;
private String lastName;
@Indexed private String userId;
private ContactInfo contactInfo = new ContactInfo();
}
请注意PersonalInfo
对象中的userId已编入索引。
我的目标是使用spring数据通过userIds查询redis中的UserProfile
个对象。
CrudRepository
接口将无法直接执行findByUserId()
,除非我在UserProfile对象中有userId。
我不想直接在UserProfile对象中使用userId,如果有更好的方法来编写查询以通过userid查找用户。
关于我如何做到这一点的任何建议?
更新: 我将以下方法添加到存储库中:
public interface UserProfileRepository extends CrudRepository<UserProfile, String> {
List<UserProfile> findByPersonalInfo_UserId(String userId);
}
但是在代码中调用此方法时,我得到以下错误。不确定我使用的redis / spring库是否存在问题。我正在使用
例外:
java.lang.NoSuchMethodError: org.springframework.data.keyvalue.core.query.KeyValueQuery.getCriteria()Ljava/lang/Object;
at org.springframework.data.redis.repository.query.RedisQueryCreator.complete(RedisQueryCreator.java:101) ~[spring-data-redis-1.8.6.RELEASE.jar:na]
at org.springframework.data.redis.repository.query.RedisQueryCreator.complete(RedisQueryCreator.java:41) ~[spring-data-redis-1.8.6.RELEASE.jar:na]
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery.createQuery(KeyValuePartTreeQuery.java:184) ~[spring-data-keyvalue-1.2.1.RELEASE.jar:na]
at org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery.prepareQuery(KeyValuePartTreeQuery.java:128) ~[spring-data-keyvalue-1.2.1.RELEASE.jar:na]
at org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery.execute(KeyValuePartTreeQuery.java:87) ~[spring-data-keyvalue-1.2.1.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) ~[spring-data-commons-1.13.1.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at com.sun.proxy.$Proxy66.findByPersonalInfo_UserId(Unknown Source) ~[na:na]
更新2: 我可以通过将springboot版本更改为1.5.6.RELEASE来修复上述异常。
然而,现在我面临的问题是,当我通过userid查询时,它并没有给我UserProfiles,即使有匹配。
例如,redis-cli显示:
KEYS *
UserProfile:d0876c1f-5684-4ee4-acbb-7a92b7fa25ae
UserProfile:3591e476-29d7-4c3c-a7e5-6272231f96e0
UserProfile:3591e476-29d7-4c3c-a7e5-6272231f96e0:idx
UserProfile:d0876c1f-5684-4ee4-acbb-7a92b7fa25ae:idx
UserProfile:51814a77-bf40-4912-b700-cfa50d1c4b25
UserProfile:personalInfo.userId:adrian.tremblay
UserProfile:66ba8276-1bb0-47a0-a54d-4c9d99b8bf80
UserProfile:66ba8276-1bb0-47a0-a54d-4c9d99b8bf80:idx
UserProfile:personalInfo.userId:anthony.turner
UserProfile:personalInfo.userId:ashleigh.hayes
UserProfile:a81356b0-27ef-4a34-92a3-629be5114f0e
UserProfile
当我执行findAll,findById时,它会给我结果。当我执行findByPersonalInfo_UserId()并传递诸如:anthony.turner或ashleigh.hayes之类的值时,什么都没有显示出来。我是否以不正确的格式提供userId?我尝试了一些不同的东西,但没有用。
更新3:我还尝试删除UserProfile对象中的@Reference(以便redis对象变平,而不是指向引用)。但这也没有帮助。
答案 0 :(得分:0)
尝试命名您的方法,不要使用任何下划线:
List<UserProfile> findByPersonalInfoUserId(String userId);
有类似的案例,对我有用。也不需要@Reference
注释。
使用spring-boot-starter-parent 2.0.3.RELEASE
答案 1 :(得分:0)
我遇到了同样的情况,
基本上,如果您有一个引用,则Redis会在内部存储该引用的ID,由于需要获取整个对象以进行匹配,因此无法直接查询该ID,这是Redis(或任何基于哈希/非关系数据库的缺点) )。
您可能会问为什么不可能做到这一点,从技术上讲,它是可以做到的,但是它将占用大量处理器和内存,最终会影响性能,而Redis以其性能着称。
@Reference仅应使用,并且仅当您希望在多个对象(此处为UserInfo)中共享一个对象(此处为PersonalInfo)时使用。
可能的解决方案,如果您想使用 @Reference (假设UserProfile的'id'不等于PersonalInfo的userId): 我在此答案结尾处的个人解决方案:
注意:上面@Aurimas的解决方案很好,最适合您的情况,如果您不放置引用,它将创建一个新对象,该对象将存储在UserProfile Object中,但其中的任何更改PersonalInfo特定于此UserProfile,不会反映在其他UserProfile对象中。但是它的优点是它将是可查询的:-)
因此,根据您的情况,我建议您放弃@Reference for PersonalInfo,因为从逻辑上讲,不应共享它(即Personal ;-)),然后继续使用@Aurimas解决方案。 >
答案 2 :(得分:-1)
自定义查询目前不支持@Reference
序列化和反序列化。
自定义查询的where子句中不允许使用@Reference
注释标记的字段。
来源:
https://github.com/3pillarlabs/spring-data-simpledb#reference