Skip to content

Commit 7c20658

Browse files
committed
Polishing.
This change extracts entity modifying behaviour into separate methods, so it doesn't appear as an unexpected side effect of the creation of aggregate changes. Also some formatting. Original pull request #1196 See #1137
1 parent a1a87a4 commit 7c20658

File tree

3 files changed

+64
-31
lines changed

3 files changed

+64
-31
lines changed

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

+38-15
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,9 @@ public <T> T save(T instance) {
150150

151151
RelationalPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(instance.getClass());
152152

153-
Function<T, MutableAggregateChange<T>> changeCreator = persistentEntity.isNew(instance) ? this::createInsertChange
154-
: this::createUpdateChange;
153+
Function<T, MutableAggregateChange<T>> changeCreator = persistentEntity.isNew(instance)
154+
? entity -> createInsertChange(prepareVersionForInsert(entity))
155+
: entity -> createUpdateChange(prepareVersionForUpdate(entity));
155156

156157
return store(instance, changeCreator, persistentEntity);
157158
}
@@ -170,7 +171,7 @@ public <T> T insert(T instance) {
170171

171172
RelationalPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(instance.getClass());
172173

173-
return store(instance, this::createInsertChange, persistentEntity);
174+
return store(instance, entity -> createInsertChange(prepareVersionForInsert(entity)), persistentEntity);
174175
}
175176

176177
/**
@@ -187,7 +188,7 @@ public <T> T update(T instance) {
187188

188189
RelationalPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(instance.getClass());
189190

190-
return store(instance, this::createUpdateChange, persistentEntity);
191+
return store(instance, entity -> createUpdateChange(prepareVersionForUpdate(entity)), persistentEntity);
191192
}
192193

193194
/*
@@ -365,6 +366,21 @@ private <T> void deleteTree(Object id, @Nullable T entity, Class<T> domainType)
365366

366367
private <T> MutableAggregateChange<T> createInsertChange(T instance) {
367368

369+
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forSave(instance);
370+
jdbcEntityInsertWriter.write(instance, aggregateChange);
371+
return aggregateChange;
372+
}
373+
374+
private <T> MutableAggregateChange<T> createUpdateChange(EntityAndPreviousVersion<T> entityAndVersion) {
375+
376+
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forSave(entityAndVersion.entity,
377+
entityAndVersion.version);
378+
jdbcEntityUpdateWriter.write(entityAndVersion.entity, aggregateChange);
379+
return aggregateChange;
380+
}
381+
382+
private <T> T prepareVersionForInsert(T instance) {
383+
368384
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(instance);
369385
T preparedInstance = instance;
370386
if (persistentEntity.hasVersionProperty()) {
@@ -375,31 +391,26 @@ private <T> MutableAggregateChange<T> createInsertChange(T instance) {
375391
preparedInstance = RelationalEntityVersionUtils.setVersionNumberOnEntity( //
376392
instance, initialVersion, persistentEntity, converter);
377393
}
378-
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forSave(preparedInstance);
379-
jdbcEntityInsertWriter.write(preparedInstance, aggregateChange);
380-
return aggregateChange;
394+
return preparedInstance;
381395
}
382396

383-
private <T> MutableAggregateChange<T> createUpdateChange(T instance) {
397+
private <T> EntityAndPreviousVersion<T> prepareVersionForUpdate(T instance) {
384398

385399
RelationalPersistentEntity<T> persistentEntity = getRequiredPersistentEntity(instance);
386400
T preparedInstance = instance;
387401
Number previousVersion = null;
388402
if (persistentEntity.hasVersionProperty()) {
389403
// If the root aggregate has a version property, increment it.
390-
previousVersion = RelationalEntityVersionUtils.getVersionNumberFromEntity(instance,
391-
persistentEntity, converter);
404+
previousVersion = RelationalEntityVersionUtils.getVersionNumberFromEntity(instance, persistentEntity, converter);
392405

393406
Assert.notNull(previousVersion, "The root aggregate cannot be updated because the version property is null.");
394407

395408
long newVersion = previousVersion.longValue() + 1;
396409

397-
preparedInstance = RelationalEntityVersionUtils.setVersionNumberOnEntity(instance, newVersion,
398-
persistentEntity, converter);
410+
preparedInstance = RelationalEntityVersionUtils.setVersionNumberOnEntity(instance, newVersion, persistentEntity,
411+
converter);
399412
}
400-
MutableAggregateChange<T> aggregateChange = MutableAggregateChange.forSave(preparedInstance, previousVersion);
401-
jdbcEntityUpdateWriter.write(preparedInstance, aggregateChange);
402-
return aggregateChange;
413+
return new EntityAndPreviousVersion<>(preparedInstance, previousVersion);
403414
}
404415

405416
@SuppressWarnings("unchecked")
@@ -489,4 +500,16 @@ private <T> T triggerBeforeDelete(@Nullable T aggregateRoot, Object id, MutableA
489500

490501
return null;
491502
}
503+
504+
private static class EntityAndPreviousVersion<T> {
505+
506+
private final T entity;
507+
private final Number version;
508+
509+
EntityAndPreviousVersion(T entity, @Nullable Number version) {
510+
511+
this.entity = entity;
512+
this.version = version;
513+
}
514+
}
492515
}

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

+8-5
Original file line numberDiff line numberDiff line change
@@ -821,9 +821,10 @@ void saveAndUpdateAggregateWithImmutableVersion() {
821821

822822
@Test // GH-1137
823823
void testUpdateEntityWithVersionDoesNotTriggerAnewConstructorInvocation() {
824+
824825
AggregateWithImmutableVersion aggregateWithImmutableVersion = new AggregateWithImmutableVersion(null, null);
825826

826-
final AggregateWithImmutableVersion savedRoot = template.save(aggregateWithImmutableVersion);
827+
AggregateWithImmutableVersion savedRoot = template.save(aggregateWithImmutableVersion);
827828

828829
assertThat(savedRoot).isNotNull();
829830
assertThat(savedRoot.version).isEqualTo(0L);
@@ -836,12 +837,12 @@ void testUpdateEntityWithVersionDoesNotTriggerAnewConstructorInvocation() {
836837

837838
AggregateWithImmutableVersion.clearConstructorInvocationData();
838839

839-
final AggregateWithImmutableVersion updatedRoot = template.save(savedRoot);
840+
AggregateWithImmutableVersion updatedRoot = template.save(savedRoot);
840841

841842
assertThat(updatedRoot).isNotNull();
842843
assertThat(updatedRoot.version).isEqualTo(1L);
843844

844-
// Expect only one assignnment of the version to AggregateWithImmutableVersion
845+
// Expect only one assignment of the version to AggregateWithImmutableVersion
845846
assertThat(AggregateWithImmutableVersion.constructorInvocations).containsOnly(new ConstructorInvocation(savedRoot.id, updatedRoot.version));
846847
}
847848

@@ -1261,6 +1262,7 @@ public static void clearConstructorInvocationData() {
12611262
}
12621263

12631264
public AggregateWithImmutableVersion(Long id, Long version) {
1265+
12641266
constructorInvocations.add(new ConstructorInvocation(id, version));
12651267
this.id = id;
12661268
this.version = version;
@@ -1270,8 +1272,9 @@ public AggregateWithImmutableVersion(Long id, Long version) {
12701272
@Value
12711273
@EqualsAndHashCode
12721274
private static class ConstructorInvocation {
1273-
private Long id;
1274-
private Long version;
1275+
1276+
Long id;
1277+
Long version;
12751278
}
12761279

12771280
@Data

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

+18-11
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
import lombok.AllArgsConstructor;
2424
import lombok.Data;
25-
2625
import lombok.RequiredArgsConstructor;
26+
2727
import org.junit.jupiter.api.BeforeEach;
2828
import org.junit.jupiter.api.Test;
2929
import org.junit.jupiter.api.extension.ExtendWith;
@@ -115,7 +115,7 @@ public void callbackOnSave() {
115115
assertThat(last).isEqualTo(third);
116116
}
117117

118-
@Test
118+
@Test // GH-1137
119119
void savePreparesInstanceWithInitialVersion_onInsert() {
120120

121121
EntityWithVersion entity = new EntityWithVersion(1L);
@@ -125,11 +125,12 @@ void savePreparesInstanceWithInitialVersion_onInsert() {
125125

126126
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
127127
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
128+
128129
EntityWithVersion afterConvert = (EntityWithVersion) aggregateRootCaptor.getValue();
129130
assertThat(afterConvert.getVersion()).isEqualTo(0L);
130131
}
131132

132-
@Test
133+
@Test // GH-1137
133134
void savePreparesInstanceWithInitialVersion_onInsert_whenVersionPropertyIsImmutable() {
134135

135136
EntityWithImmutableVersion entity = new EntityWithImmutableVersion(1L, null);
@@ -139,11 +140,12 @@ void savePreparesInstanceWithInitialVersion_onInsert_whenVersionPropertyIsImmuta
139140

140141
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
141142
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
143+
142144
EntityWithImmutableVersion afterConvert = (EntityWithImmutableVersion) aggregateRootCaptor.getValue();
143145
assertThat(afterConvert.getVersion()).isEqualTo(0L);
144146
}
145147

146-
@Test // DATAJDBC-507
148+
@Test // GH-1137
147149
void savePreparesInstanceWithInitialVersion_onInsert_whenVersionPropertyIsPrimitiveType() {
148150

149151
EntityWithPrimitiveVersion entity = new EntityWithPrimitiveVersion(1L);
@@ -153,11 +155,12 @@ void savePreparesInstanceWithInitialVersion_onInsert_whenVersionPropertyIsPrimit
153155

154156
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
155157
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
158+
156159
EntityWithPrimitiveVersion afterConvert = (EntityWithPrimitiveVersion) aggregateRootCaptor.getValue();
157160
assertThat(afterConvert.getVersion()).isEqualTo(1L);
158161
}
159162

160-
@Test // DATAJDBC-507
163+
@Test // GH-1137
161164
void savePreparesInstanceWithInitialVersion_onInsert__whenVersionPropertyIsImmutableAndPrimitiveType() {
162165

163166
EntityWithImmutablePrimitiveVersion entity = new EntityWithImmutablePrimitiveVersion(1L, 0L);
@@ -167,11 +170,13 @@ void savePreparesInstanceWithInitialVersion_onInsert__whenVersionPropertyIsImmut
167170

168171
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
169172
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
170-
EntityWithImmutablePrimitiveVersion afterConvert = (EntityWithImmutablePrimitiveVersion) aggregateRootCaptor.getValue();
173+
174+
EntityWithImmutablePrimitiveVersion afterConvert = (EntityWithImmutablePrimitiveVersion) aggregateRootCaptor
175+
.getValue();
171176
assertThat(afterConvert.getVersion()).isEqualTo(1L);
172177
}
173178

174-
@Test
179+
@Test // GH-1137
175180
void savePreparesChangeWithPreviousVersion_onUpdate() {
176181

177182
when(dataAccessStrategy.updateWithVersion(any(), any(), any())).thenReturn(true);
@@ -183,11 +188,12 @@ void savePreparesChangeWithPreviousVersion_onUpdate() {
183188

184189
ArgumentCaptor<Object> aggregateChangeCaptor = ArgumentCaptor.forClass(Object.class);
185190
verify(callbacks).callback(eq(BeforeSaveCallback.class), any(), aggregateChangeCaptor.capture());
191+
186192
MutableAggregateChange<?> aggregateChange = (MutableAggregateChange<?>) aggregateChangeCaptor.getValue();
187193
assertThat(aggregateChange.getPreviousVersion()).isEqualTo(1L);
188194
}
189195

190-
@Test
196+
@Test // GH-1137
191197
void savePreparesInstanceWithNextVersion_onUpdate() {
192198

193199
when(dataAccessStrategy.updateWithVersion(any(), any(), any())).thenReturn(true);
@@ -199,11 +205,12 @@ void savePreparesInstanceWithNextVersion_onUpdate() {
199205

200206
ArgumentCaptor<Object> aggregateRootCaptor = ArgumentCaptor.forClass(Object.class);
201207
verify(callbacks).callback(eq(BeforeSaveCallback.class), aggregateRootCaptor.capture(), any());
208+
202209
EntityWithVersion afterConvert = (EntityWithVersion) aggregateRootCaptor.getValue();
203210
assertThat(afterConvert.getVersion()).isEqualTo(2L);
204211
}
205212

206-
@Test
213+
@Test // GH-1137
207214
void savePreparesInstanceWithNextVersion_onUpdate_whenVersionPropertyIsImmutable() {
208215

209216
when(dataAccessStrategy.updateWithVersion(any(), any(), any())).thenReturn(true);
@@ -218,7 +225,7 @@ void savePreparesInstanceWithNextVersion_onUpdate_whenVersionPropertyIsImmutable
218225
assertThat(afterConvert.getVersion()).isEqualTo(2L);
219226
}
220227

221-
@Test
228+
@Test // GH-1137
222229
void deletePreparesChangeWithPreviousVersion_onDeleteByInstance() {
223230

224231
EntityWithImmutableVersion entity = new EntityWithImmutableVersion(1L, 1L);
@@ -228,11 +235,11 @@ void deletePreparesChangeWithPreviousVersion_onDeleteByInstance() {
228235

229236
ArgumentCaptor<Object> aggregateChangeCaptor = ArgumentCaptor.forClass(Object.class);
230237
verify(callbacks).callback(eq(BeforeDeleteCallback.class), any(), aggregateChangeCaptor.capture());
238+
231239
MutableAggregateChange<?> aggregateChange = (MutableAggregateChange<?>) aggregateChangeCaptor.getValue();
232240
assertThat(aggregateChange.getPreviousVersion()).isEqualTo(1L);
233241
}
234242

235-
236243
@Test // DATAJDBC-393
237244
public void callbackOnDelete() {
238245

0 commit comments

Comments
 (0)