Browse Source

Determine and set the value for entity @Version before conversion to DbActions to simplify execution context.

This change incorporates one test from https://github.com/spring-projects/spring-data-relational/pull/1150

Original pull request #1196
Closes #1137
pull/1564/head
Chirag Tailor 4 years ago committed by Jens Schauder
parent
commit
a1a87a44ef
No known key found for this signature in database
GPG Key ID: 45CC872F17423DBF
  1. 6
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java
  2. 89
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutionContext.java
  3. 57
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java
  4. 6
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutorContextImmutableUnitTests.java
  5. 25
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutorContextUnitTests.java
  6. 45
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java
  7. 160
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateUnitTests.java
  8. 10
      spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java
  9. 13
      spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DefaultAggregateChange.java
  10. 37
      spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java
  11. 23
      spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java
  12. 6
      spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java
  13. 57
      spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java

6
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/AggregateChangeExecutor.java

@ -51,10 +51,8 @@ class AggregateChangeExecutor { @@ -51,10 +51,8 @@ class AggregateChangeExecutor {
aggregateChange.forEachAction(action -> execute(action, executionContext));
T root = executionContext.populateIdsIfNecessary();
root = root == null ? aggregateChange.getEntity() : root;
if (root != null) {
root = executionContext.populateRootVersionIfNecessary(root);
if (root == null) {
root = aggregateChange.getEntity();
}
return root;

89
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutionContext.java

@ -40,7 +40,6 @@ import org.springframework.data.mapping.PersistentPropertyPath; @@ -40,7 +40,6 @@ import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.relational.core.conversion.DbAction;
import org.springframework.data.relational.core.conversion.DbActionExecutionResult;
import org.springframework.data.relational.core.conversion.RelationalEntityVersionUtils;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
@ -65,7 +64,6 @@ class JdbcAggregateChangeExecutionContext { @@ -65,7 +64,6 @@ class JdbcAggregateChangeExecutionContext {
private final DataAccessStrategy accessStrategy;
private final Map<DbAction<?>, DbActionExecutionResult> results = new LinkedHashMap<>();
@Nullable private Long version;
JdbcAggregateChangeExecutionContext(JdbcConverter converter, DataAccessStrategy accessStrategy) {
@ -76,28 +74,8 @@ class JdbcAggregateChangeExecutionContext { @@ -76,28 +74,8 @@ class JdbcAggregateChangeExecutionContext {
<T> void executeInsertRoot(DbAction.InsertRoot<T> insert) {
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(insert.getEntityType());
Object id;
if (persistentEntity.hasVersionProperty()) {
RelationalPersistentProperty versionProperty = persistentEntity.getVersionProperty();
Assert.state(versionProperty != null, "Version property must not be null at this stage.");
long initialVersion = versionProperty.getActualType().isPrimitive() ? 1L : 0;
T rootEntity = RelationalEntityVersionUtils.setVersionNumberOnEntity( //
insert.getEntity(), initialVersion, persistentEntity, converter);
id = accessStrategy.insert(rootEntity, insert.getEntityType(), Identifier.empty(), insert.getIdValueSource());
setNewVersion(initialVersion);
} else {
id = accessStrategy.insert(insert.getEntity(), insert.getEntityType(), Identifier.empty(),
insert.getIdValueSource());
}
Object id = accessStrategy.insert(insert.getEntity(), insert.getEntityType(), Identifier.empty(),
insert.getIdValueSource());
add(new DbActionExecutionResult(insert, id));
}
@ -125,12 +103,9 @@ class JdbcAggregateChangeExecutionContext { @@ -125,12 +103,9 @@ class JdbcAggregateChangeExecutionContext {
<T> void executeUpdateRoot(DbAction.UpdateRoot<T> update) {
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(update.getEntityType());
if (persistentEntity.hasVersionProperty()) {
updateWithVersion(update, persistentEntity);
if (update.getPreviousVersion() != null) {
updateWithVersion(update);
} else {
updateWithoutVersion(update);
}
}
@ -147,16 +122,10 @@ class JdbcAggregateChangeExecutionContext { @@ -147,16 +122,10 @@ class JdbcAggregateChangeExecutionContext {
<T> void executeDeleteRoot(DbAction.DeleteRoot<T> delete) {
if (delete.getPreviousVersion() != null) {
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(delete.getEntityType());
if (persistentEntity.hasVersionProperty()) {
accessStrategy.deleteWithVersion(delete.getId(), delete.getEntityType(), delete.getPreviousVersion());
return;
}
accessStrategy.deleteWithVersion(delete.getId(), delete.getEntityType(), delete.getPreviousVersion());
} else {
accessStrategy.delete(delete.getId(), delete.getEntityType());
}
accessStrategy.delete(delete.getId(), delete.getEntityType());
}
<T> void executeDelete(DbAction.Delete<T> delete) {
@ -258,36 +227,6 @@ class JdbcAggregateChangeExecutionContext { @@ -258,36 +227,6 @@ class JdbcAggregateChangeExecutionContext {
return identifier;
}
private void setNewVersion(long version) {
Assert.isNull(this.version, "A new version was set a second time.");
this.version = version;
}
private long getNewVersion() {
Assert.notNull(version, "A new version was requested, but none was set.");
return version;
}
private boolean hasNewVersion() {
return version != null;
}
<T> T populateRootVersionIfNecessary(T newRoot) {
if (!hasNewVersion()) {
return newRoot;
}
// Does the root entity have a version attribute?
RelationalPersistentEntity<T> persistentEntity = (RelationalPersistentEntity<T>) context
.getRequiredPersistentEntity(newRoot.getClass());
return RelationalEntityVersionUtils.setVersionNumberOnEntity(newRoot, getNewVersion(), persistentEntity, converter);
}
@SuppressWarnings("unchecked")
@Nullable
<T> T populateIdsIfNecessary() {
@ -378,20 +317,12 @@ class JdbcAggregateChangeExecutionContext { @@ -378,20 +317,12 @@ class JdbcAggregateChangeExecutionContext {
}
}
private <T> void updateWithVersion(DbAction.UpdateRoot<T> update, RelationalPersistentEntity<T> persistentEntity) {
// If the root aggregate has a version property, increment it.
Number previousVersion = RelationalEntityVersionUtils.getVersionNumberFromEntity(update.getEntity(),
persistentEntity, converter);
private <T> void updateWithVersion(DbAction.UpdateRoot<T> update) {
Number previousVersion = update.getPreviousVersion();
Assert.notNull(previousVersion, "The root aggregate cannot be updated because the version property is null.");
setNewVersion(previousVersion.longValue() + 1);
T rootEntity = RelationalEntityVersionUtils.setVersionNumberOnEntity(update.getEntity(), getNewVersion(),
persistentEntity, converter);
if (!accessStrategy.updateWithVersion(rootEntity, update.getEntityType(), previousVersion)) {
if (!accessStrategy.updateWithVersion(update.getEntity(), update.getEntityType(), previousVersion)) {
throw new OptimisticLockingFailureException(String.format(UPDATE_FAILED_OPTIMISTIC_LOCKING, update.getEntity()));
}

57
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 the original author or authors.
* Copyright 2017-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -35,8 +35,10 @@ import org.springframework.data.relational.core.conversion.MutableAggregateChang @@ -35,8 +35,10 @@ import org.springframework.data.relational.core.conversion.MutableAggregateChang
import org.springframework.data.relational.core.conversion.RelationalEntityDeleteWriter;
import org.springframework.data.relational.core.conversion.RelationalEntityInsertWriter;
import org.springframework.data.relational.core.conversion.RelationalEntityUpdateWriter;
import org.springframework.data.relational.core.conversion.RelationalEntityVersionUtils;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.relational.core.mapping.event.*;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.lang.Nullable;
@ -51,6 +53,7 @@ import org.springframework.util.Assert; @@ -51,6 +53,7 @@ import org.springframework.util.Assert;
* @author Christoph Strobl
* @author Milan Milanov
* @author Myeonghyeon Lee
* @author Chirag Tailor
*/
public class JdbcAggregateTemplate implements JdbcAggregateOperations {
@ -63,6 +66,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { @@ -63,6 +66,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
private final DataAccessStrategy accessStrategy;
private final AggregateChangeExecutor executor;
private final JdbcConverter converter;
private EntityCallbacks entityCallbacks = EntityCallbacks.create();
@ -86,6 +90,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { @@ -86,6 +90,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
this.publisher = publisher;
this.context = context;
this.accessStrategy = dataAccessStrategy;
this.converter = converter;
this.jdbcEntityInsertWriter = new RelationalEntityInsertWriter(context);
this.jdbcEntityUpdateWriter = new RelationalEntityUpdateWriter(context);
@ -115,6 +120,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { @@ -115,6 +120,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
this.publisher = publisher;
this.context = context;
this.accessStrategy = dataAccessStrategy;
this.converter = converter;
this.jdbcEntityInsertWriter = new RelationalEntityInsertWriter(context);
this.jdbcEntityUpdateWriter = new RelationalEntityUpdateWriter(context);
@ -332,7 +338,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { @@ -332,7 +338,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
MutableAggregateChange<T> change = changeCreator.apply(aggregateRoot);
aggregateRoot = triggerBeforeSave(aggregateRoot, change);
aggregateRoot = triggerBeforeSave(change.getEntity(), change);
change.setEntity(aggregateRoot);
@ -359,21 +365,58 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { @@ -359,21 +365,58 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
private <T> MutableAggregateChange<T> createInsertChange(T instance) {
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forSave(instance);
jdbcEntityInsertWriter.write(instance, aggregateChange);
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(instance);
T preparedInstance = instance;
if (persistentEntity.hasVersionProperty()) {
RelationalPersistentProperty versionProperty = persistentEntity.getRequiredVersionProperty();
long initialVersion = versionProperty.getActualType().isPrimitive() ? 1L : 0;
preparedInstance = RelationalEntityVersionUtils.setVersionNumberOnEntity( //
instance, initialVersion, persistentEntity, converter);
}
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forSave(preparedInstance);
jdbcEntityInsertWriter.write(preparedInstance, aggregateChange);
return aggregateChange;
}
private <T> MutableAggregateChange<T> createUpdateChange(T instance) {
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forSave(instance);
jdbcEntityUpdateWriter.write(instance, aggregateChange);
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(instance);
T preparedInstance = instance;
Number previousVersion = null;
if (persistentEntity.hasVersionProperty()) {
// If the root aggregate has a version property, increment it.
previousVersion = RelationalEntityVersionUtils.getVersionNumberFromEntity(instance,
persistentEntity, converter);
Assert.notNull(previousVersion, "The root aggregate cannot be updated because the version property is null.");
long newVersion = previousVersion.longValue() + 1;
preparedInstance = RelationalEntityVersionUtils.setVersionNumberOnEntity(instance, newVersion,
persistentEntity, converter);
}
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forSave(preparedInstance, previousVersion);
jdbcEntityUpdateWriter.write(preparedInstance, aggregateChange);
return aggregateChange;
}
@SuppressWarnings("unchecked")
private <T> RelationalPersistentEntity<T> getRequiredPersistentEntity(T instance) {
return (RelationalPersistentEntity<T>) context.getRequiredPersistentEntity(instance.getClass());
}
private <T> MutableAggregateChange<T> createDeletingChange(Object id, @Nullable T entity, Class<T> domainType) {
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forDelete(domainType, entity);
Number previousVersion = null;
if (entity != null) {
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(entity);
if (persistentEntity.hasVersionProperty()) {
previousVersion = RelationalEntityVersionUtils.getVersionNumberFromEntity(entity, persistentEntity, converter);
}
}
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forDelete(domainType, entity, previousVersion);
jdbcEntityDeleteWriter.write(id, aggregateChange);
return aggregateChange;
}

6
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutorContextImmutableUnitTests.java

@ -64,7 +64,7 @@ public class JdbcAggregateChangeExecutorContextImmutableUnitTests { @@ -64,7 +64,7 @@ public class JdbcAggregateChangeExecutorContextImmutableUnitTests {
}
@Test // DATAJDBC-453
public void afterInsertRootIdAndVersionMaybeUpdated() {
public void afterInsertRootIdMaybeUpdated() {
// note that the root entity isn't the original one, but a new instance with the version set.
when(accessStrategy.insert(any(DummyEntity.class), eq(DummyEntity.class), eq(Identifier.empty()),
@ -76,10 +76,6 @@ public class JdbcAggregateChangeExecutorContextImmutableUnitTests { @@ -76,10 +76,6 @@ public class JdbcAggregateChangeExecutorContextImmutableUnitTests {
assertThat(newRoot).isNotNull();
assertThat(newRoot.id).isEqualTo(23L);
newRoot = executionContext.populateRootVersionIfNecessary(newRoot);
assertThat(newRoot.version).isEqualTo(1);
}
@Test // DATAJDBC-453

25
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutorContextUnitTests.java

@ -70,7 +70,7 @@ public class JdbcAggregateChangeExecutorContextUnitTests { @@ -70,7 +70,7 @@ public class JdbcAggregateChangeExecutorContextUnitTests {
}
@Test // DATAJDBC-453
public void afterInsertRootIdAndVersionMaybeUpdated() {
public void afterInsertRootIdMaybeUpdated() {
when(accessStrategy.insert(root, DummyEntity.class, Identifier.empty(), IdValueSource.GENERATED)).thenReturn(23L);
@ -80,22 +80,6 @@ public class JdbcAggregateChangeExecutorContextUnitTests { @@ -80,22 +80,6 @@ public class JdbcAggregateChangeExecutorContextUnitTests {
assertThat(newRoot).isNull();
assertThat(root.id).isEqualTo(23L);
executionContext.populateRootVersionIfNecessary(root);
assertThat(root.version).isEqualTo(1);
}
@Test // DATAJDBC-507
public void afterInsertNotPrimitiveVersionShouldBeZero() {
DummyEntityNonPrimitiveVersion dummyEntityNonPrimitiveVersion = new DummyEntityNonPrimitiveVersion();
executionContext
.executeInsertRoot(new DbAction.InsertRoot<>(dummyEntityNonPrimitiveVersion, IdValueSource.GENERATED));
executionContext.populateRootVersionIfNecessary(dummyEntityNonPrimitiveVersion);
assertThat(dummyEntityNonPrimitiveVersion.version).isEqualTo(0);
}
@Test // DATAJDBC-453
@ -218,19 +202,12 @@ public class JdbcAggregateChangeExecutorContextUnitTests { @@ -218,19 +202,12 @@ public class JdbcAggregateChangeExecutorContextUnitTests {
private static class DummyEntity {
@Id Long id;
@Version long version;
Content content;
List<Content> list = new ArrayList<>();
}
private static class DummyEntityNonPrimitiveVersion {
@Id Long id;
@Version Long version;
}
private static class Content {
@Id Long id;
}

45
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java

@ -819,6 +819,32 @@ class JdbcAggregateTemplateIntegrationTests { @@ -819,6 +819,32 @@ class JdbcAggregateTemplateIntegrationTests {
.hasRootCauseInstanceOf(OptimisticLockingFailureException.class);
}
@Test // GH-1137
void testUpdateEntityWithVersionDoesNotTriggerAnewConstructorInvocation() {
AggregateWithImmutableVersion aggregateWithImmutableVersion = new AggregateWithImmutableVersion(null, null);
final AggregateWithImmutableVersion savedRoot = template.save(aggregateWithImmutableVersion);
assertThat(savedRoot).isNotNull();
assertThat(savedRoot.version).isEqualTo(0L);
assertThat(AggregateWithImmutableVersion.constructorInvocations).containsExactly(
new ConstructorInvocation(null, null), // Initial invocation, done by client
new ConstructorInvocation(null, savedRoot.version), // Assigning the version
new ConstructorInvocation(savedRoot.id, savedRoot.version) // Assigning the id
);
AggregateWithImmutableVersion.clearConstructorInvocationData();
final AggregateWithImmutableVersion updatedRoot = template.save(savedRoot);
assertThat(updatedRoot).isNotNull();
assertThat(updatedRoot.version).isEqualTo(1L);
// Expect only one assignnment of the version to AggregateWithImmutableVersion
assertThat(AggregateWithImmutableVersion.constructorInvocations).containsOnly(new ConstructorInvocation(savedRoot.id, updatedRoot.version));
}
@Test // DATAJDBC-219 Test that a delete with a version attribute works as expected.
void deleteAggregateWithVersion() {
@ -1227,6 +1253,25 @@ class JdbcAggregateTemplateIntegrationTests { @@ -1227,6 +1253,25 @@ class JdbcAggregateTemplateIntegrationTests {
@Id Long id;
@Version Long version;
private final static List<ConstructorInvocation> constructorInvocations = new ArrayList<>();
public static void clearConstructorInvocationData() {
constructorInvocations.clear();
}
public AggregateWithImmutableVersion(Long id, Long version) {
constructorInvocations.add(new ConstructorInvocation(id, version));
this.id = id;
this.version = version;
}
}
@Value
@EqualsAndHashCode
private static class ConstructorInvocation {
private Long id;
private Long version;
}
@Data

160
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateUnitTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 the original author or authors.
* Copyright 2019-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,13 +23,16 @@ import static org.mockito.Mockito.*; @@ -23,13 +23,16 @@ import static org.mockito.Mockito.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.convert.BasicJdbcConverter;
@ -55,6 +58,7 @@ import org.springframework.data.relational.core.mapping.event.BeforeSaveCallback @@ -55,6 +58,7 @@ import org.springframework.data.relational.core.mapping.event.BeforeSaveCallback
* @author Christoph Strobl
* @author Mark Paluch
* @author Milan Milanov
* @author Chirag Tailor
*/
@ExtendWith(MockitoExtension.class)
public class JdbcAggregateTemplateUnitTests {
@ -111,6 +115,124 @@ public class JdbcAggregateTemplateUnitTests { @@ -111,6 +115,124 @@ public class JdbcAggregateTemplateUnitTests {
assertThat(last).isEqualTo(third);
}
@Test
void savePreparesInstanceWithInitialVersion_onInsert() {
EntityWithVersion entity = new EntityWithVersion(1L);
when(callbacks.callback(any(), any(), any())).thenReturn(entity, entity);
template.save(entity);
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
EntityWithVersion afterConvert = (EntityWithVersion) aggregateRootCaptor.getValue();
assertThat(afterConvert.getVersion()).isEqualTo(0L);
}
@Test
void savePreparesInstanceWithInitialVersion_onInsert_whenVersionPropertyIsImmutable() {
EntityWithImmutableVersion entity = new EntityWithImmutableVersion(1L, null);
when(callbacks.callback(any(), any(), any())).thenReturn(entity, entity);
template.save(entity);
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
EntityWithImmutableVersion afterConvert = (EntityWithImmutableVersion) aggregateRootCaptor.getValue();
assertThat(afterConvert.getVersion()).isEqualTo(0L);
}
@Test // DATAJDBC-507
void savePreparesInstanceWithInitialVersion_onInsert_whenVersionPropertyIsPrimitiveType() {
EntityWithPrimitiveVersion entity = new EntityWithPrimitiveVersion(1L);
when(callbacks.callback(any(), any(), any())).thenReturn(entity, entity);
template.save(entity);
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
EntityWithPrimitiveVersion afterConvert = (EntityWithPrimitiveVersion) aggregateRootCaptor.getValue();
assertThat(afterConvert.getVersion()).isEqualTo(1L);
}
@Test // DATAJDBC-507
void savePreparesInstanceWithInitialVersion_onInsert__whenVersionPropertyIsImmutableAndPrimitiveType() {
EntityWithImmutablePrimitiveVersion entity = new EntityWithImmutablePrimitiveVersion(1L, 0L);
when(callbacks.callback(any(), any(), any())).thenReturn(entity, entity);
template.save(entity);
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
EntityWithImmutablePrimitiveVersion afterConvert = (EntityWithImmutablePrimitiveVersion) aggregateRootCaptor.getValue();
assertThat(afterConvert.getVersion()).isEqualTo(1L);
}
@Test
void savePreparesChangeWithPreviousVersion_onUpdate() {
when(dataAccessStrategy.updateWithVersion(any(), any(), any())).thenReturn(true);
EntityWithVersion entity = new EntityWithVersion(1L);
entity.setVersion(1L);
when(callbacks.callback(any(), any(), any())).thenReturn(entity, entity);
template.save(entity);
ArgumentCaptor<Object> aggregateChangeCaptor = ArgumentCaptor.forClass(Object.class);
verify(callbacks).callback(eq(BeforeSaveCallback.class), any(), aggregateChangeCaptor.capture());
MutableAggregateChange<?> aggregateChange = (MutableAggregateChange<?>) aggregateChangeCaptor.getValue();
assertThat(aggregateChange.getPreviousVersion()).isEqualTo(1L);
}
@Test
void savePreparesInstanceWithNextVersion_onUpdate() {
when(dataAccessStrategy.updateWithVersion(any(), any(), any())).thenReturn(true);
EntityWithVersion entity = new EntityWithVersion(1L);
entity.setVersion(1L);
when(callbacks.callback(any(), any(), any())).thenReturn(entity, entity);
template.save(entity);
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
EntityWithVersion afterConvert = (EntityWithVersion) aggregateRootCaptor.getValue();
assertThat(afterConvert.getVersion()).isEqualTo(2L);
}
@Test
void savePreparesInstanceWithNextVersion_onUpdate_whenVersionPropertyIsImmutable() {
when(dataAccessStrategy.updateWithVersion(any(), any(), any())).thenReturn(true);
EntityWithImmutableVersion entity = new EntityWithImmutableVersion(1L, 1L);
when(callbacks.callback(any(), any(), any())).thenReturn(entity, entity);
template.save(entity);
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
EntityWithImmutableVersion afterConvert = (EntityWithImmutableVersion) aggregateRootCaptor.getValue();
assertThat(afterConvert.getVersion()).isEqualTo(2L);
}
@Test
void deletePreparesChangeWithPreviousVersion_onDeleteByInstance() {
EntityWithImmutableVersion entity = new EntityWithImmutableVersion(1L, 1L);
when(callbacks.callback(any(), any(), any())).thenReturn(entity, entity);
template.delete(entity, EntityWithImmutableVersion.class);
ArgumentCaptor<Object> aggregateChangeCaptor = ArgumentCaptor.forClass(Object.class);
verify(callbacks).callback(eq(BeforeDeleteCallback.class), any(), aggregateChangeCaptor.capture());
MutableAggregateChange<?> aggregateChange = (MutableAggregateChange<?>) aggregateChangeCaptor.getValue();
assertThat(aggregateChange.getPreviousVersion()).isEqualTo(1L);
}
@Test // DATAJDBC-393
public void callbackOnDelete() {
@ -209,4 +331,40 @@ public class JdbcAggregateTemplateUnitTests { @@ -209,4 +331,40 @@ public class JdbcAggregateTemplateUnitTests {
private String name;
}
@Data
@RequiredArgsConstructor
private static class EntityWithVersion {
@Column("id1") @Id private final Long id;
@Version private Long version;
}
@Data
@RequiredArgsConstructor
private static class EntityWithImmutableVersion {
@Column("id1") @Id private final Long id;
@Version private final Long version;
}
@Data
@RequiredArgsConstructor
private static class EntityWithPrimitiveVersion {
@Column("id1") @Id private final Long id;
@Version private long version;
}
@Data
@RequiredArgsConstructor
private static class EntityWithImmutablePrimitiveVersion {
@Column("id1") @Id private final Long id;
@Version private final long version;
}
}

10
spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DbAction.java

@ -166,14 +166,22 @@ public interface DbAction<T> { @@ -166,14 +166,22 @@ public interface DbAction<T> {
private final T entity;
public UpdateRoot(T entity) {
@Nullable private final Number previousVersion;
public UpdateRoot(T entity, @Nullable Number previousVersion) {
this.entity = entity;
this.previousVersion = previousVersion;
}
public T getEntity() {
return this.entity;
}
@Nullable
public Number getPreviousVersion() {
return previousVersion;
}
public String toString() {
return "DbAction.UpdateRoot(entity=" + this.getEntity() + ")";
}

13
spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/DefaultAggregateChange.java

@ -27,6 +27,7 @@ import org.springframework.util.Assert; @@ -27,6 +27,7 @@ import org.springframework.util.Assert;
*
* @author Jens Schauder
* @author Mark Paluch
* @author Chirag Tailor
* @since 2.0
*/
class DefaultAggregateChange<T> implements MutableAggregateChange<T> {
@ -41,11 +42,15 @@ class DefaultAggregateChange<T> implements MutableAggregateChange<T> { @@ -41,11 +42,15 @@ class DefaultAggregateChange<T> implements MutableAggregateChange<T> {
/** Aggregate root, to which the change applies, if available */
private @Nullable T entity;
public DefaultAggregateChange(Kind kind, Class<T> entityType, @Nullable T entity) {
/** The previous version assigned to the instance being changed, if available */
@Nullable private final Number previousVersion;
public DefaultAggregateChange(Kind kind, Class<T> entityType, @Nullable T entity, @Nullable Number previousVersion) {
this.kind = kind;
this.entityType = entityType;
this.entity = entity;
this.previousVersion = previousVersion;
}
/**
@ -95,6 +100,12 @@ class DefaultAggregateChange<T> implements MutableAggregateChange<T> { @@ -95,6 +100,12 @@ class DefaultAggregateChange<T> implements MutableAggregateChange<T> {
this.entity = aggregateRoot;
}
@Nullable
@Override
public Number getPreviousVersion() {
return previousVersion;
}
/*
* (non-Javadoc)
* @see org.springframework.data.relational.core.conversion.AggregateChange#getEntity()

37
spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MutableAggregateChange.java

@ -24,6 +24,7 @@ import org.springframework.util.ClassUtils; @@ -24,6 +24,7 @@ import org.springframework.util.ClassUtils;
*
* @author Jens Schauder
* @author Mark Paluch
* @author Chirag Tailor
* @since 2.0
*/
public interface MutableAggregateChange<T> extends AggregateChange<T> {
@ -36,12 +37,25 @@ public interface MutableAggregateChange<T> extends AggregateChange<T> { @@ -36,12 +37,25 @@ public interface MutableAggregateChange<T> extends AggregateChange<T> {
* @return the {@link MutableAggregateChange} for saving the root {@code entity}.
* @since 1.2
*/
@SuppressWarnings("unchecked")
static <T> MutableAggregateChange<T> forSave(T entity) {
return forSave(entity, null);
}
/**
* Factory method to create an {@link MutableAggregateChange} for saving entities.
*
* @param entity aggregate root to save.
* @param previousVersion the previous version assigned to the instance being saved. May be {@literal null}.
* @param <T> entity type.
* @return the {@link MutableAggregateChange} for saving the root {@code entity}.
* @since 2.4
*/
@SuppressWarnings("unchecked")
static <T> MutableAggregateChange<T> forSave(T entity, @Nullable Number previousVersion) {
Assert.notNull(entity, "Entity must not be null");
return new DefaultAggregateChange<>(Kind.SAVE, (Class<T>) ClassUtils.getUserClass(entity), entity);
return new DefaultAggregateChange<>(Kind.SAVE, (Class<T>) ClassUtils.getUserClass(entity), entity, previousVersion);
}
/**
@ -70,10 +84,24 @@ public interface MutableAggregateChange<T> extends AggregateChange<T> { @@ -70,10 +84,24 @@ public interface MutableAggregateChange<T> extends AggregateChange<T> {
* @since 1.2
*/
static <T> MutableAggregateChange<T> forDelete(Class<T> entityClass, @Nullable T entity) {
return forDelete(entityClass, entity, null);
}
/**
* Factory method to create an {@link MutableAggregateChange} for deleting entities.
*
* @param entityClass aggregate root type.
* @param entity aggregate root to delete.
* @param previousVersion the previous version assigned to the instance being saved. May be {@literal null}.
* @param <T> entity type.
* @return the {@link MutableAggregateChange} for deleting the root {@code entity}.
* @since 2.4
*/
static <T> MutableAggregateChange<T> forDelete(Class<T> entityClass, @Nullable T entity, @Nullable Number previousVersion) {
Assert.notNull(entityClass, "Entity class must not be null");
return new DefaultAggregateChange<>(Kind.DELETE, entityClass, entity);
return new DefaultAggregateChange<>(Kind.DELETE, entityClass, entity, previousVersion);
}
/**
@ -89,4 +117,7 @@ public interface MutableAggregateChange<T> extends AggregateChange<T> { @@ -89,4 +117,7 @@ public interface MutableAggregateChange<T> extends AggregateChange<T> {
* @param aggregateRoot may be {@literal null} if the change refers to a list of aggregates or references it by id.
*/
void setEntity(@Nullable T aggregateRoot);
@Nullable
Number getPreviousVersion();
}

23
spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/RelationalEntityDeleteWriter.java

@ -37,6 +37,7 @@ import org.springframework.util.Assert; @@ -37,6 +37,7 @@ import org.springframework.util.Assert;
* @author Bastian Wilhelm
* @author Tyler Van Gorder
* @author Myeonghyeon Lee
* @author Chirag Tailor
*/
public class RelationalEntityDeleteWriter implements EntityWriter<Object, MutableAggregateChange<?>> {
@ -88,7 +89,7 @@ public class RelationalEntityDeleteWriter implements EntityWriter<Object, Mutabl @@ -88,7 +89,7 @@ public class RelationalEntityDeleteWriter implements EntityWriter<Object, Mutabl
return actions;
}
private <T> List<DbAction<?>> deleteRoot(Object id, AggregateChange<T> aggregateChange) {
private <T> List<DbAction<?>> deleteRoot(Object id, MutableAggregateChange<T> aggregateChange) {
List<DbAction<?>> deleteReferencedActions = deleteReferencedEntities(id, aggregateChange);
@ -98,7 +99,7 @@ public class RelationalEntityDeleteWriter implements EntityWriter<Object, Mutabl @@ -98,7 +99,7 @@ public class RelationalEntityDeleteWriter implements EntityWriter<Object, Mutabl
}
actions.addAll(deleteReferencedActions);
actions.add(new DbAction.DeleteRoot<>(id, aggregateChange.getEntityType(), getVersion(aggregateChange)));
actions.add(new DbAction.DeleteRoot<>(id, aggregateChange.getEntityType(), aggregateChange.getPreviousVersion()));
return actions;
}
@ -121,22 +122,4 @@ public class RelationalEntityDeleteWriter implements EntityWriter<Object, Mutabl @@ -121,22 +122,4 @@ public class RelationalEntityDeleteWriter implements EntityWriter<Object, Mutabl
return actions;
}
@Nullable
private Number getVersion(AggregateChange<?> aggregateChange) {
RelationalPersistentEntity<?> persistentEntity = context
.getRequiredPersistentEntity(aggregateChange.getEntityType());
if (!persistentEntity.hasVersionProperty()) {
return null;
}
Object entity = aggregateChange.getEntity();
if (entity == null) {
return null;
}
return (Number) persistentEntity.getPropertyAccessor(entity)
.getProperty(persistentEntity.getRequiredVersionProperty());
}
}

6
spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java

@ -52,6 +52,7 @@ class WritingContext { @@ -52,6 +52,7 @@ class WritingContext {
private final Map<PathNode, DbAction<?>> previousActions = new HashMap<>();
private final Map<PersistentPropertyPath<RelationalPersistentProperty>, List<PathNode>> nodesCache = new HashMap<>();
private final IdValueSource rootIdValueSource;
@Nullable private final Number previousVersion;
WritingContext(RelationalMappingContext context, Object root, MutableAggregateChange<?> aggregateChange) {
@ -59,6 +60,7 @@ class WritingContext { @@ -59,6 +60,7 @@ class WritingContext {
this.root = root;
this.entity = aggregateChange.getEntity();
this.entityType = aggregateChange.getEntityType();
this.previousVersion = aggregateChange.getPreviousVersion();
this.rootIdValueSource = IdValueSource.forInstance(root,
context.getRequiredPersistentEntity(aggregateChange.getEntityType()));
this.paths = context.findPersistentPropertyPaths(entityType, (p) -> p.isEntity() && !p.isEmbedded());
@ -88,7 +90,7 @@ class WritingContext { @@ -88,7 +90,7 @@ class WritingContext {
List<DbAction<?>> update() {
List<DbAction<?>> actions = new ArrayList<>();
actions.add(setRootAction(new DbAction.UpdateRoot<>(entity)));
actions.add(setRootAction(new DbAction.UpdateRoot<>(entity, previousVersion)));
actions.addAll(deleteReferenced());
actions.addAll(insertReferenced());
return actions;
@ -103,7 +105,7 @@ class WritingContext { @@ -103,7 +105,7 @@ class WritingContext {
actions.addAll(insertReferenced());
} else {
actions.add(setRootAction(new DbAction.UpdateRoot<>(entity)));
actions.add(setRootAction(new DbAction.UpdateRoot<>(entity, previousVersion)));
actions.addAll(deleteReferenced());
actions.addAll(insertReferenced());
}

57
spring-data-relational/src/test/java/org/springframework/data/relational/core/conversion/RelationalEntityWriterUnitTests.java

@ -85,7 +85,7 @@ public class RelationalEntityWriterUnitTests { @@ -85,7 +85,7 @@ public class RelationalEntityWriterUnitTests {
SingleReferenceEntity entity = new SingleReferenceEntity(null);
MutableAggregateChange<SingleReferenceEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity, null);
converter.write(entity, aggregateChange);
@ -107,7 +107,7 @@ public class RelationalEntityWriterUnitTests { @@ -107,7 +107,7 @@ public class RelationalEntityWriterUnitTests {
PrimitiveLongIdEntity entity = new PrimitiveLongIdEntity();
MutableAggregateChange<PrimitiveLongIdEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, PrimitiveLongIdEntity.class, entity);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, PrimitiveLongIdEntity.class, entity, null);
converter.write(entity, aggregateChange);
@ -129,7 +129,7 @@ public class RelationalEntityWriterUnitTests { @@ -129,7 +129,7 @@ public class RelationalEntityWriterUnitTests {
PrimitiveIntIdEntity entity = new PrimitiveIntIdEntity();
MutableAggregateChange<PrimitiveIntIdEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, PrimitiveIntIdEntity.class, entity);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, PrimitiveIntIdEntity.class, entity, null);
converter.write(entity, aggregateChange);
@ -153,7 +153,7 @@ public class RelationalEntityWriterUnitTests { @@ -153,7 +153,7 @@ public class RelationalEntityWriterUnitTests {
entity.other = new Element(2L);
MutableAggregateChange<EmbeddedReferenceEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EmbeddedReferenceEntity.class, entity);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EmbeddedReferenceEntity.class, entity, null);
converter.write(entity, aggregateChange);
@ -177,7 +177,7 @@ public class RelationalEntityWriterUnitTests { @@ -177,7 +177,7 @@ public class RelationalEntityWriterUnitTests {
entity.other = new Element(null);
MutableAggregateChange<SingleReferenceEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity, null);
converter.write(entity, aggregateChange);
@ -203,7 +203,7 @@ public class RelationalEntityWriterUnitTests { @@ -203,7 +203,7 @@ public class RelationalEntityWriterUnitTests {
entity.primitiveIntIdEntity = new PrimitiveIntIdEntity();
MutableAggregateChange<EntityWithReferencesToPrimitiveIdEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EntityWithReferencesToPrimitiveIdEntity.class, entity);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EntityWithReferencesToPrimitiveIdEntity.class, entity, null);
converter.write(entity, aggregateChange);
@ -230,7 +230,7 @@ public class RelationalEntityWriterUnitTests { @@ -230,7 +230,7 @@ public class RelationalEntityWriterUnitTests {
SingleReferenceEntity entity = new SingleReferenceEntity(SOME_ENTITY_ID);
MutableAggregateChange<SingleReferenceEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity, 1L);
converter.write(entity, aggregateChange);
@ -239,10 +239,11 @@ public class RelationalEntityWriterUnitTests { @@ -239,10 +239,11 @@ public class RelationalEntityWriterUnitTests {
DbAction::getEntityType, //
DbActionTestSupport::extractPath, //
DbActionTestSupport::actualEntityType, //
DbActionTestSupport::isWithDependsOn) //
DbActionTestSupport::isWithDependsOn, //
dbAction -> dbAction instanceof UpdateRoot ? ((UpdateRoot<?>) dbAction).getPreviousVersion() : null) //
.containsExactly( //
tuple(UpdateRoot.class, SingleReferenceEntity.class, "", SingleReferenceEntity.class, false), //
tuple(Delete.class, Element.class, "other", null, false) //
tuple(UpdateRoot.class, SingleReferenceEntity.class, "", SingleReferenceEntity.class, false, 1L), //
tuple(Delete.class, Element.class, "other", null, false, null) //
);
}
@ -253,7 +254,7 @@ public class RelationalEntityWriterUnitTests { @@ -253,7 +254,7 @@ public class RelationalEntityWriterUnitTests {
entity.other = new Element(null);
MutableAggregateChange<SingleReferenceEntity> aggregateChange = new DefaultAggregateChange<>(
AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity);
AggregateChange.Kind.SAVE, SingleReferenceEntity.class, entity, 1L);
converter.write(entity, aggregateChange);
@ -276,7 +277,7 @@ public class RelationalEntityWriterUnitTests { @@ -276,7 +277,7 @@ public class RelationalEntityWriterUnitTests {
SetContainer entity = new SetContainer(null);
MutableAggregateChange<SetContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
SetContainer.class, entity);
SetContainer.class, entity, null);
converter.write(entity, aggregateChange);
@ -299,7 +300,7 @@ public class RelationalEntityWriterUnitTests { @@ -299,7 +300,7 @@ public class RelationalEntityWriterUnitTests {
entity.elements.add(new Element(null));
MutableAggregateChange<SetContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
SetContainer.class, entity);
SetContainer.class, entity, null);
converter.write(entity, aggregateChange);
List<DbAction<?>> actions = extractActions(aggregateChange);
@ -342,7 +343,7 @@ public class RelationalEntityWriterUnitTests { @@ -342,7 +343,7 @@ public class RelationalEntityWriterUnitTests {
);
MutableAggregateChange<CascadingReferenceEntity> aggregateChange = new DefaultAggregateChange<>(
AggregateChange.Kind.SAVE, CascadingReferenceEntity.class, entity);
AggregateChange.Kind.SAVE, CascadingReferenceEntity.class, entity, null);
converter.write(entity, aggregateChange);
@ -404,7 +405,7 @@ public class RelationalEntityWriterUnitTests { @@ -404,7 +405,7 @@ public class RelationalEntityWriterUnitTests {
);
MutableAggregateChange<CascadingReferenceEntity> aggregateChange = new DefaultAggregateChange<>(
AggregateChange.Kind.SAVE, CascadingReferenceEntity.class, entity);
AggregateChange.Kind.SAVE, CascadingReferenceEntity.class, entity, 1L);
converter.write(entity, aggregateChange);
@ -456,7 +457,7 @@ public class RelationalEntityWriterUnitTests { @@ -456,7 +457,7 @@ public class RelationalEntityWriterUnitTests {
MapContainer entity = new MapContainer(null);
MutableAggregateChange<MapContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
MapContainer.class, entity);
MapContainer.class, entity, null);
converter.write(entity, aggregateChange);
@ -476,7 +477,7 @@ public class RelationalEntityWriterUnitTests { @@ -476,7 +477,7 @@ public class RelationalEntityWriterUnitTests {
entity.elements.put("two", new Element(null));
MutableAggregateChange<MapContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
MapContainer.class, entity);
MapContainer.class, entity, null);
converter.write(entity, aggregateChange);
List<DbAction<?>> actions = extractActions(aggregateChange);
@ -520,7 +521,7 @@ public class RelationalEntityWriterUnitTests { @@ -520,7 +521,7 @@ public class RelationalEntityWriterUnitTests {
entity.elements.put("b", new Element(null));
MutableAggregateChange<MapContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
MapContainer.class, entity);
MapContainer.class, entity, null);
converter.write(entity, aggregateChange);
List<DbAction<?>> actions = extractActions(aggregateChange);
@ -560,7 +561,7 @@ public class RelationalEntityWriterUnitTests { @@ -560,7 +561,7 @@ public class RelationalEntityWriterUnitTests {
ListContainer entity = new ListContainer(null);
MutableAggregateChange<ListContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
ListContainer.class, entity);
ListContainer.class, entity, null);
converter.write(entity, aggregateChange);
@ -580,7 +581,7 @@ public class RelationalEntityWriterUnitTests { @@ -580,7 +581,7 @@ public class RelationalEntityWriterUnitTests {
entity.elements.add(new Element(null));
MutableAggregateChange<ListContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
ListContainer.class, entity);
ListContainer.class, entity, null);
converter.write(entity, aggregateChange);
List<DbAction<?>> actions = extractActions(aggregateChange);
@ -612,7 +613,7 @@ public class RelationalEntityWriterUnitTests { @@ -612,7 +613,7 @@ public class RelationalEntityWriterUnitTests {
entity.elements.put("one", new Element(null));
MutableAggregateChange<MapContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
MapContainer.class, entity);
MapContainer.class, entity, 1L);
converter.write(entity, aggregateChange);
@ -636,7 +637,7 @@ public class RelationalEntityWriterUnitTests { @@ -636,7 +637,7 @@ public class RelationalEntityWriterUnitTests {
entity.elements.add(new Element(null));
MutableAggregateChange<ListContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
ListContainer.class, entity);
ListContainer.class, entity, 1L);
converter.write(entity, aggregateChange);
@ -661,7 +662,7 @@ public class RelationalEntityWriterUnitTests { @@ -661,7 +662,7 @@ public class RelationalEntityWriterUnitTests {
listMapContainer.maps.get(0).elements.put("one", new Element(null));
MutableAggregateChange<ListMapContainer> aggregateChange = new DefaultAggregateChange<>(AggregateChange.Kind.SAVE,
ListMapContainer.class, listMapContainer);
ListMapContainer.class, listMapContainer, 1L);
converter.write(listMapContainer, aggregateChange);
@ -689,7 +690,7 @@ public class RelationalEntityWriterUnitTests { @@ -689,7 +690,7 @@ public class RelationalEntityWriterUnitTests {
listMapContainer.maps.get(0).elements.put("one", new NoIdElement());
MutableAggregateChange<NoIdListMapContainer> aggregateChange = new DefaultAggregateChange<>(
AggregateChange.Kind.SAVE, NoIdListMapContainer.class, listMapContainer);
AggregateChange.Kind.SAVE, NoIdListMapContainer.class, listMapContainer, 1L);
converter.write(listMapContainer, aggregateChange);
@ -716,7 +717,7 @@ public class RelationalEntityWriterUnitTests { @@ -716,7 +717,7 @@ public class RelationalEntityWriterUnitTests {
// the embedded is null !!!
MutableAggregateChange<EmbeddedReferenceChainEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EmbeddedReferenceChainEntity.class, entity);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EmbeddedReferenceChainEntity.class, entity, null);
converter.write(entity, aggregateChange);
@ -741,7 +742,7 @@ public class RelationalEntityWriterUnitTests { @@ -741,7 +742,7 @@ public class RelationalEntityWriterUnitTests {
// the embedded is null !!!
MutableAggregateChange<RootWithEmbeddedReferenceChainEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, RootWithEmbeddedReferenceChainEntity.class, root);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, RootWithEmbeddedReferenceChainEntity.class, root, null);
converter.write(root, aggregateChange);
@ -769,7 +770,7 @@ public class RelationalEntityWriterUnitTests { @@ -769,7 +770,7 @@ public class RelationalEntityWriterUnitTests {
root.elements.add(new Element(null));
root.elements.add(new Element(2L));
MutableAggregateChange<ListContainer> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, ListContainer.class, root);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, ListContainer.class, root, null);
converter.write(root, aggregateChange);
@ -817,7 +818,7 @@ public class RelationalEntityWriterUnitTests { @@ -817,7 +818,7 @@ public class RelationalEntityWriterUnitTests {
entity.primitiveIntIdEntities.add(new PrimitiveIntIdEntity());
MutableAggregateChange<EntityWithReferencesToPrimitiveIdEntity> aggregateChange = //
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EntityWithReferencesToPrimitiveIdEntity.class, entity);
new DefaultAggregateChange<>(AggregateChange.Kind.SAVE, EntityWithReferencesToPrimitiveIdEntity.class, entity, null);
converter.write(entity, aggregateChange);

Loading…
Cancel
Save