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

@EnableSpannerAuditing fails if saved entity contains UUID #3143

Open
Klompara opened this issue Aug 20, 2024 · 1 comment
Open

@EnableSpannerAuditing fails if saved entity contains UUID #3143

Klompara opened this issue Aug 20, 2024 · 1 comment
Labels

Comments

@Klompara
Copy link

Runtime
Java 21
Spring Boot 3.3.2
spring-cloud-gcp-dependencies 5.5.0

Describe the bug
If a Spanner Entity contains UUID as a primary key and Spanner auditing is configured, repository save will throw a InaccessibleObjectException
Spring framework uses reflection in order to make jdk internal fields accessible. This is disabled since JDK 16 and throws this exception. Only occurs if Spanner Auditing is enabled.

Stacktrace

java.lang.reflect.InaccessibleObjectException: Unable to make field private final long java.util.UUID.mostSigBits accessible: module java.base does not "opens java.util" to unnamed module @4f9a3314
        at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:391)
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:367)
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:315)
        at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:183)
        at java.base/java.lang.reflect.Field.setAccessible(Field.java:177)
        at org.springframework.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:804)
        at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:616)
        at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:728)
        at org.springframework.data.mapping.context.AbstractMappingContext.doAddPersistentEntity(AbstractMappingContext.java:471)
        at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:424)
        at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:320)
        at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:334)
        at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:97)
        at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:147)
        at org.springframework.data.mapping.context.PersistentPropertyPathFactory.lambda$from$2(PersistentPropertyPathFactory.java:259)
        at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:321)
        at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:264)
        at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:235)
        at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:166)
        at org.springframework.data.mapping.context.AbstractMappingContext.doFindPersistentPropertyPaths(AbstractMappingContext.java:374)
        at org.springframework.data.mapping.context.AbstractMappingContext.findPersistentPropertyPaths(AbstractMappingContext.java:358)
        at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingAuditingMetadata.findPropertyPaths(MappingAuditableBeanWrapperFactory.java:150)
        at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingAuditingMetadata.<init>(MappingAuditableBeanWrapperFactory.java:124)
        at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory.lambda$getBeanWrapperFor$0(MappingAuditableBeanWrapperFactory.java:85)
        at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330)
        at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory.lambda$getBeanWrapperFor$1(MappingAuditableBeanWrapperFactory.java:84)
        at org.springframework.data.mapping.context.PersistentEntities.lambda$mapOnContext$2(PersistentEntities.java:144)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
        at java.base/java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:1034)
        at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
        at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
        at org.springframework.data.mapping.context.PersistentEntities.mapOnContext(PersistentEntities.java:145)
        at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory.lambda$getBeanWrapperFor$3(MappingAuditableBeanWrapperFactory.java:82)
        at java.base/java.util.Optional.flatMap(Optional.java:289)
        at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory.getBeanWrapperFor(MappingAuditableBeanWrapperFactory.java:76)
        at org.springframework.data.auditing.AuditingHandlerSupport.touch(AuditingHandlerSupport.java:132)
        at org.springframework.data.auditing.AuditingHandlerSupport.markModified(AuditingHandlerSupport.java:127)
        at org.springframework.data.auditing.AuditingHandler.markModified(AuditingHandler.java:98)
        at java.base/java.util.Collections$SingletonList.forEach(Collections.java:5186)
        at com.google.cloud.spring.data.spanner.repository.support.SpannerAuditingEventListener.onApplicationEvent(SpannerAuditingEventListener.java:43)
        at com.google.cloud.spring.data.spanner.repository.support.SpannerAuditingEventListener.onApplicationEvent(SpannerAuditingEventListener.java:28)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:452)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:385)
        at com.google.cloud.spring.data.spanner.core.SpannerTemplate.maybeEmitEvent(SpannerTemplate.java:732)
        at com.google.cloud.spring.data.spanner.core.SpannerTemplate.applySaveMutations(SpannerTemplate.java:380)
        at com.google.cloud.spring.data.spanner.core.SpannerTemplate.upsert(SpannerTemplate.java:348)
        at com.google.cloud.spring.data.spanner.repository.support.SimpleSpannerRepository.save(SimpleSpannerRepository.java:81)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:277)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158)
        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.$Proxy115.save(Unknown Source)
@ldetmer ldetmer added type: bug Something isn't working priority: p2 labels Aug 21, 2024
@ldetmer
Copy link
Contributor

ldetmer commented Aug 22, 2024

I was able to repro this by adding @EnableSpannerAuditing to our exist spanner test + adding UUIDs. I will have the team look into this and see how we can help. You could also try reaching out to Spring as it seems like this is an issue with their auditing handling.

@ldetmer ldetmer assigned ldetmer and unassigned ldetmer Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants