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

Support from Spring Framework sans Boot #259

Open
Grogdunn opened this issue Jun 1, 2023 · 2 comments
Open

Support from Spring Framework sans Boot #259

Grogdunn opened this issue Jun 1, 2023 · 2 comments

Comments

@Grogdunn
Copy link
Contributor

Grogdunn commented Jun 1, 2023

Hi,
I need to "mix" a SQL database (Postrgres+Hibernate in production) and Redis. I've struggled a lot, but with no luck.

I wish to enable transactions, so I've configured:

@Bean(name = "redisTemplate")
@Primary
public StringRedisTemplate redisTemplate(JedisConnectionFactory connectionFactory) {
    final var stringRedisTemplate = new StringRedisTemplate(connectionFactory);
    stringRedisTemplate.setEnableTransactionSupport(true);
    return stringRedisTemplate;
}

But at runtime, I get this error:

org.springframework.data.keyvalue.core.UncategorizedKeyValueException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "org.springframework.data.redis.connection.RedisKeyCommands.exists(byte[])" is null
	at org.springframework.data.keyvalue.core.KeyValuePersistenceExceptionTranslator.translateExceptionIfPossible(KeyValuePersistenceExceptionTranslator.java:51)
	at org.springframework.data.keyvalue.core.KeyValueTemplate.resolveExceptionIfPossible(KeyValueTemplate.java:405)
	at org.springframework.data.keyvalue.core.KeyValueTemplate.execute(KeyValueTemplate.java:316)
	at org.springframework.data.keyvalue.core.KeyValueTemplate.insert(KeyValueTemplate.java:162)
	at org.springframework.data.keyvalue.core.KeyValueTemplate.insert(KeyValueTemplate.java:149)
	at org.springframework.data.keyvalue.repository.support.SimpleKeyValueRepository.save(SimpleKeyValueRepository.java:73)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:288)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
	at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:516)
	at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:628)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:168)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
	at jdk.proxy2/jdk.proxy2.$Proxy70.save(Unknown Source)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:173)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:173)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
	at jdk.proxy2/jdk.proxy2.$Proxy73.save(Unknown Source)
	at it.grogdunn.Facade.lambda$generateScrapData$0(Facade.java:25)
	at java.base/java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:104)
	at java.base/java.util.stream.IntPipeline$Head.forEach(IntPipeline.java:617)
	at it.grogdunn.Facade.generateScrapData(Facade.java:25)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:702)
	at it.grogdunn.Facade$$SpringCGLIB$$0.generateScrapData(<generated>)
	at it.grogdunn.Main.main(Main.java:11)
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "org.springframework.data.redis.connection.RedisKeyCommands.exists(byte[])" is null
	at com.redis.om.spring.audit.EntityAuditor.lambda$processEntity$0(EntityAuditor.java:25)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:406)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:373)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:360)
	at com.redis.om.spring.audit.EntityAuditor.processEntity(EntityAuditor.java:25)
	at com.redis.om.spring.RedisEnhancedKeyValueAdapter.put(RedisEnhancedKeyValueAdapter.java:132)
	at org.springframework.data.keyvalue.core.KeyValueTemplate.lambda$insert$0(KeyValueTemplate.java:169)
	at org.springframework.data.keyvalue.core.KeyValueTemplate.execute(KeyValueTemplate.java:314)
	... 50 more

Have I done something "illegal"?

Example code: https://github.com/Grogdunn/redis-om-spring-classic/tree/redis-transaction-issue

@bsbodden
Copy link
Contributor

bsbodden commented Jun 1, 2023

@Grogdunn No, you're not doing anything wrong, it's likely a bug, but we are still working on properly doing transactions in OM. This is a poorly understood subject (with Redis), and I want to build something robust that plays well with JPA. I'll test your app and see if it is a matter of checking a few NPEs here and there.

@bsbodden
Copy link
Contributor

bsbodden commented Jun 6, 2023

I sent you a PR to you demo repo, see if it makes any sense and whether it preserves your original intent

@bsbodden bsbodden changed the title Wrong behavior with transaction support? Support from Spring Framework sans Boot Jun 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants