UncategorizedKeyValueException 试图通过具有事务支持的存储库保存 RedisHash

UncategorizedKeyValueException trying to save RedisHash via repository with transaction support

问题:

启用事务支持后(redisTemplate.setEnableTransactionSupport(true)) 我 UncategorizedKeyValueException 试图在存储库中保存 @RedisHash

禁用事务支持时一切正常。

通过 RedisTemplate 的直接操作在事务支持下运行良好。

堆栈跟踪:

...
at org.lorem.LoremController.create(TestController.java:41)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
... 17 more
Caused by: java.lang.NullPointerException
at org.springframework.data.redis.core.RedisKeyValueAdapter.lambda$put[=10=](RedisKeyValueAdapter.java:236)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:171)
at org.springframework.data.redis.core.RedisKeyValueAdapter.put(RedisKeyValueAdapter.java:231)
at org.springframework.data.keyvalue.core.KeyValueTemplate.lambda$insert[=10=](KeyValueTemplate.java:165)
at org.springframework.data.keyvalue.core.KeyValueTemplate.execute(KeyValueTemplate.java:343)
... 56 more

背景:

我正在使用 spring-boot-starter-data-redis:2.0.4.RELEASE

配置:

@Bean
@Primary
StringRedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    StringRedisTemplate redisTemplate = new StringRedisTemplate();
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    redisTemplate.setEnableTransactionSupport(true);
    redisTemplate.afterPropertiesSet();

    return redisTemplate;
}

Redis哈希:

@RedisHash("test")
public class Test {
    private String id;
    private String field;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }
}

存储库:

public interface TestRepository extends CrudRepository<Test, String> {
}

谢谢:)

更新:

RedisKeyValueAdapter 中的以下行中断:

boolean isNew = connection.del(objectKey) == 0;

del() returns null 因为它在事务中运行。存储库不应该在启用事务支持的情况下工作吗?

Redis 存储库不适用于 Redis 事务。这在这里解释:https://jira.spring.io/browse/DATAREDIS-862

Redis Repositories do not work with Redis transactions as operations that change the underlying data are queued and executed at the end of the transaction. These commands return null. However, we require the outcome immediately at invocation time.