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

Using audit annotation in an embedded Java record fails with Cannot set property #1694

Closed
jipipi opened this issue Dec 12, 2023 · 7 comments
Closed
Assignees
Labels
type: bug A general bug

Comments

@jipipi
Copy link

jipipi commented Dec 12, 2023

If you declare audit annotation like @CreatedBy in an embedded java record then an exception is thrown :
IllegalState Cannot set property createdUser because no setter, no wither and it's not part of the persistence constructor public springdata.jdbc.bug.UserAudit(java.lang.String,java.time.Instant,java.lang.String,java.time.LocalDateTime)

This issue also happens for other audit annotation @LastModifiedBy, @LastModifiedDate and @CreatedDate
If the annotation are not in an embedded object it's work.

Exemple of code to reproduce issue

public record Car (
        @Id Long id,
        String name,
        @Embedded.Empty() 
        UserAudit userAudit
){}
public record UserAudit(@LastModifiedBy String modifiedUser,
                        @LastModifiedDate Instant modifiedDate,
                        @CreatedBy String createdUser,
                        @CreatedDate LocalDateTime createdDate) {}
CREATE TABLE IF NOT EXISTS Car (
    id INTEGER IDENTITY PRIMARY KEY,
     name VARCHAR(100),
     -- UserAudit attributes
    modified_user  varchar(255),
    modified_date  timestamp,
    created_user   varchar(255),
    created_date   timestamp
);

Here a project to reproduce the bug (the test failed) : https://github.com/jipipi/spring-data-jdbc-bug1

spring-data-jdbc : 3.2.0
java 17

@jipipi jipipi changed the title Using audit annotation in an embedded java record not wort Using audit annotation in an embedded java record not work Dec 12, 2023
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 12, 2023
@schauder
Copy link
Contributor

schauder commented Jan 3, 2024

Is this specific to the embeded entity being a record?

@schauder schauder added the status: waiting-for-feedback We need additional information before we can continue label Jan 3, 2024
@schauder schauder self-assigned this Jan 3, 2024
@jipipi
Copy link
Author

jipipi commented Jan 4, 2024

Is this specific to the embeded entity being a record?

If i remember well, I reproduced the issue with classes instead of record

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 4, 2024
@grzegorzt
Copy link

The problem isn't specific to records, I've encountered it with regular java class - I've attached example project.

This is embedded class:

@Value
@Builder
@Immutable
public class Audit {
  private static final Audit EMPTY = builder().build();

  @CreatedDate
  Instant createdAt;
  @CreatedBy
  String createdBy;
  @LastModifiedDate
  Instant updatedAt;
  @LastModifiedBy
  String updatedBy;

  public static Audit empty() {
    return EMPTY;
  }
}

and entity class:

@Value
@Builder(toBuilder = true)
@Immutable
@Table
public class TestEntity {
  @Id
  String id;
  @Version
  int version;
  @NonNull
  String name;
  @NonNull
  @Embedded.Empty
  @Builder.Default
  Audit audit = Audit.empty();
}

When spring boot version 3.1.7 is used (you can easilty change it in build.gradle), everything works. In 3.2.1 the exception is thrown:
java.lang.IllegalStateException: Cannot set property createdBy because no setter, no wither and it's not part of the persistence constructor ....

Full stacktrace:

java.lang.IllegalStateException: Cannot set property createdBy because no setter, no wither and it's not part of the persistence constructor com.bug.audit.model.Audit(java.time.Instant,java.lang.String,java.time.Instant,java.lang.String)
	at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor.setProperty(InstantiationAwarePropertyAccessor.java:93)
	at org.springframework.data.mapping.model.SimplePersistentPropertyPathAccessor.setValue(SimplePersistentPropertyPathAccessor.java:233)
	at org.springframework.data.mapping.model.SimplePersistentPropertyPathAccessor.setProperty(SimplePersistentPropertyPathAccessor.java:187)
	at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.lambda$setProperty$0(MappingAuditableBeanWrapperFactory.java:232)
	at java.base/java.lang.Iterable.forEach(Iterable.java:75)
	at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.setProperty(MappingAuditableBeanWrapperFactory.java:232)
	at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.setCreatedBy(MappingAuditableBeanWrapperFactory.java:197)
	at org.springframework.data.auditing.AuditingHandlerSupport.touchAuditor(AuditingHandlerSupport.java:169)
	at org.springframework.data.auditing.AuditingHandlerSupport.lambda$touch$0(AuditingHandlerSupport.java:136)
	at java.base/java.util.Optional.map(Optional.java:260)
	at org.springframework.data.auditing.AuditingHandlerSupport.touch(AuditingHandlerSupport.java:134)
	at org.springframework.data.auditing.AuditingHandlerSupport.markCreated(AuditingHandlerSupport.java:114)
	at org.springframework.data.auditing.AuditingHandler.markCreated(AuditingHandler.java:86)
	at org.springframework.data.auditing.IsNewAwareAuditingHandler.markAudited(IsNewAwareAuditingHandler.java:78)
	at org.springframework.data.relational.auditing.RelationalAuditingCallback.onBeforeConvert(RelationalAuditingCallback.java:61)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:281)
	at org.springframework.data.mapping.callback.EntityCallbackDiscoverer.lambda$computeCallbackInvokerFunction$1(EntityCallbackDiscoverer.java:258)
	at org.springframework.data.mapping.callback.DefaultEntityCallbacks$SimpleEntityCallbackInvoker.invokeCallback(DefaultEntityCallbacks.java:106)
	at org.springframework.data.mapping.callback.DefaultEntityCallbacks.callback(DefaultEntityCallbacks.java:87)
	at org.springframework.data.jdbc.core.JdbcAggregateTemplate.triggerBeforeConvert(JdbcAggregateTemplate.java:622)
	at org.springframework.data.jdbc.core.JdbcAggregateTemplate.beforeExecute(JdbcAggregateTemplate.java:462)
	at org.springframework.data.jdbc.core.JdbcAggregateTemplate.performSave(JdbcAggregateTemplate.java:489)
	at org.springframework.data.jdbc.core.JdbcAggregateTemplate.save(JdbcAggregateTemplate.java:168)
	at org.springframework.data.jdbc.repository.support.SimpleJdbcRepository.save(SimpleJdbcRepository.java:68)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:352)
	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.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:385)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
	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:249)
	at jdk.proxy3/jdk.proxy3.$Proxy78.save(Unknown Source)
	at com.bug.audit.EmbeddedAuditTest.shouldPersistEntity(EmbeddedAuditTest.java:49)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:728)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:218)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:214)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:139)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:119)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:94)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:89)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

bug.tar.gz

@jipipi jipipi changed the title Using audit annotation in an embedded java record not work Using audit annotation in an embedded java object not work Jan 27, 2024
@jipipi
Copy link
Author

jipipi commented Feb 8, 2024

If the embedded entity containing the audit annotation is a regular class with setter then it's work.
I updated the test case :
bug1.zip

FYI, on version 2.4.11, the record was supported.

@schauder When I debug it's failing on InstantiationAwarePropertyAccessor :

if (!creator.isCreatorParameter(property)) {
			throw new IllegalStateException(String.format(NO_CONSTRUCTOR_PARAMETER, property.getName(), creator));
}

because it's searching an EmbeddedRelationalPersistencePoperty and BasicJdbcPersistentProperty is provided:
Screenshot 2024-02-08 at 17 53 27

@dennishendriksen
Copy link

Ran into the same issue as reported by @jipipi, but instead of getting an error, no error occurs and no auditing information if persisted to the database.

Works:

public record MyEntity(
    @Id Integer id,
    @CreatedBy AggregateReference<User, Integer> createdBy,
    @CreatedDate Instant creationDate,
    @LastModifiedBy AggregateReference<User, Integer> lastModifiedBy,
    @LastModifiedDate Instant lastModifiedDate) {}

Fails:

public record MyEntity(
    @Id Integer id,
    @Embedded.Empty AuditMetadata auditMetadata) {}

public record AuditMetadata(
    @CreatedBy AggregateReference<User, Integer> createdBy,
    @CreatedDate Instant creationDate,
    @LastModifiedBy AggregateReference<User, Integer> lastModifiedBy,
    @LastModifiedDate Instant lastModifiedDate){}

My use case is reusing the same embedded AuditMetadata record in multiple entities.

@DreamStar92
Copy link

DreamStar92 commented Jun 26, 2024

@schauder

The owner (RelationalPersistentEntity) returned by EmbeddedRelationalPersistentProperty is the owner of its delegate. The creator of the owner gets the creation value from its own properties. The property of RelationalPersistentEntity is BasicRelationalPersistentProperty, which means isCreatorParameter->doGetIsCreatorParameter->maps->property.equals(referencedProperty), property is EmbeddedRelationalPersistentProperty and referencedProperty is BasicRelationalPersistentProperty, causing false to be returned.
image

image

@schauder schauder added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Jun 26, 2024
@schauder
Copy link
Contributor

Ran into the same issue [...], but instead of getting an error, no error occurs and no auditing information if persisted to the database.

This is the expected behaviour when the embedded entity is null.
We are not instantiating such entities on the fly.

@mp911de mp911de changed the title Using audit annotation in an embedded java object not work Using audit annotation in an embedded Java record fails with Cannot set property Jun 27, 2024
schauder added a commit that referenced this issue Jun 27, 2024
The reason for auditing to not work on embedded fields is that EmbeddedRelationalPersistentProperty and BasicRelationalPersisntentProperty were not considered equal even when they represent the same field.

Note: the fix is somewhat hackish since it breaks the equals contract for EmbeddedRelationalPersistentProperty.

Closes #1694
See spring-projects/spring-data-mongodb@1545e18
schauder added a commit that referenced this issue Jun 27, 2024
The reason for auditing to not work on embedded fields is that EmbeddedRelationalPersistentProperty and BasicRelationalPersisntentProperty were not considered equal even when they represent the same field.

Note: the fix is somewhat hackish since it breaks the equals contract for EmbeddedRelationalPersistentProperty.

Closes #1694
See spring-projects/spring-data-mongodb@1545e18
schauder added a commit that referenced this issue Jun 27, 2024
The reason for auditing to not work on embedded fields is that EmbeddedRelationalPersistentProperty and BasicRelationalPersisntentProperty were not considered equal even when they represent the same field.

Note: the fix is somewhat hackish since it breaks the equals contract for EmbeddedRelationalPersistentProperty.

Closes #1694
See spring-projects/spring-data-mongodb@1545e18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

6 participants