Skip to content

Commit 94f94c6

Browse files
committed
#93 - Polishing.
Formatting. Added issue to test comments. Removed the test for presence of the id in case of a potential optimistic locking exception. A deleted row is also a case of a concurrent modification and therefore should trigger the OptimisticLockingException. Original pull request: #314.
1 parent 8e6797d commit 94f94c6

File tree

3 files changed

+18
-23
lines changed

3 files changed

+18
-23
lines changed

src/main/java/org/springframework/data/r2dbc/core/DefaultDatabaseClient.java

+1
Original file line numberDiff line numberDiff line change
@@ -1297,6 +1297,7 @@ class DefaultTypedUpdateSpec<T> implements TypedUpdateSpec<T>, UpdateMatchingSpe
12971297

12981298
DefaultTypedUpdateSpec(Class<T> typeToUpdate, @Nullable SqlIdentifier table, @Nullable T objectToUpdate,
12991299
@Nullable CriteriaDefinition where) {
1300+
13001301
this.typeToUpdate = typeToUpdate;
13011302
this.table = table;
13021303
this.objectToUpdate = objectToUpdate;

src/main/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplate.java

+12-18
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import io.r2dbc.spi.Row;
1919
import io.r2dbc.spi.RowMetadata;
20-
import org.springframework.dao.OptimisticLockingFailureException;
2120
import reactor.core.publisher.Flux;
2221
import reactor.core.publisher.Mono;
2322

@@ -33,6 +32,7 @@
3332
import org.springframework.beans.factory.BeanFactoryAware;
3433
import org.springframework.core.convert.ConversionService;
3534
import org.springframework.dao.DataAccessException;
35+
import org.springframework.dao.OptimisticLockingFailureException;
3636
import org.springframework.dao.TransientDataAccessResourceException;
3737
import org.springframework.data.mapping.IdentifierAccessor;
3838
import org.springframework.data.mapping.MappingException;
@@ -377,7 +377,7 @@ <T> Mono<T> doInsert(T entity, SqlIdentifier tableName) {
377377

378378
RelationalPersistentEntity<T> persistentEntity = getRequiredEntity(entity);
379379

380-
setVersionIfNecessary(persistentEntity, entity);
380+
setVersionIfNecessary(persistentEntity, entity);
381381

382382
return this.databaseClient.insert() //
383383
.into(persistentEntity.getType()) //
@@ -388,6 +388,7 @@ <T> Mono<T> doInsert(T entity, SqlIdentifier tableName) {
388388
}
389389

390390
private <T> void setVersionIfNecessary(RelationalPersistentEntity<T> persistentEntity, T entity) {
391+
391392
RelationalPersistentProperty versionProperty = persistentEntity.getVersionProperty();
392393
if (versionProperty == null) {
393394
return;
@@ -418,45 +419,37 @@ public <T> Mono<T> update(T entity) throws DataAccessException {
418419

419420
DatabaseClient.UpdateSpec updateSpec = updateMatchingSpec;
420421
if (persistentEntity.hasVersionProperty()) {
422+
421423
updateSpec = updateMatchingSpec.matching(createMatchingVersionCriteria(entity, persistentEntity));
422424
incrementVersion(entity, persistentEntity);
423425
}
424426

425427
return updateSpec.fetch() //
426428
.rowsUpdated() //
427-
.flatMap(rowsUpdated -> rowsUpdated == 0
428-
? handleMissingUpdate(entity, persistentEntity) : Mono.just(entity));
429+
.flatMap(rowsUpdated -> rowsUpdated == 0 ? handleMissingUpdate(entity, persistentEntity) : Mono.just(entity));
429430
}
430431

431432
private <T> Mono<? extends T> handleMissingUpdate(T entity, RelationalPersistentEntity<T> persistentEntity) {
432-
if (!persistentEntity.hasVersionProperty()) {
433-
return Mono.error(new TransientDataAccessResourceException(
434-
formatTransientEntityExceptionMessage(entity, persistentEntity)));
435-
}
436433

437-
return doCount(getByIdQuery(entity, persistentEntity), entity.getClass(), persistentEntity.getTableName())
438-
.map(count -> {
439-
if (count == 0) {
440-
throw new TransientDataAccessResourceException(
441-
formatTransientEntityExceptionMessage(entity, persistentEntity));
442-
} else {
443-
throw new OptimisticLockingFailureException(
444-
formatOptimisticLockingExceptionMessage(entity, persistentEntity));
445-
}
446-
});
434+
return Mono.error(persistentEntity.hasVersionProperty()
435+
? new OptimisticLockingFailureException(formatOptimisticLockingExceptionMessage(entity, persistentEntity))
436+
: new TransientDataAccessResourceException(formatTransientEntityExceptionMessage(entity, persistentEntity)));
447437
}
448438

449439
private <T> String formatOptimisticLockingExceptionMessage(T entity, RelationalPersistentEntity<T> persistentEntity) {
440+
450441
return String.format("Failed to update table [%s]. Version does not match for row with Id [%s].",
451442
persistentEntity.getTableName(), persistentEntity.getIdentifierAccessor(entity).getIdentifier());
452443
}
453444

454445
private <T> String formatTransientEntityExceptionMessage(T entity, RelationalPersistentEntity<T> persistentEntity) {
446+
455447
return String.format("Failed to update table [%s]. Row with Id [%s] does not exist.",
456448
persistentEntity.getTableName(), persistentEntity.getIdentifierAccessor(entity).getIdentifier());
457449
}
458450

459451
private <T> void incrementVersion(T entity, RelationalPersistentEntity<T> persistentEntity) {
452+
460453
PersistentPropertyAccessor<?> propertyAccessor = persistentEntity.getPropertyAccessor(entity);
461454
RelationalPersistentProperty versionProperty = persistentEntity.getVersionProperty();
462455

@@ -471,6 +464,7 @@ private <T> void incrementVersion(T entity, RelationalPersistentEntity<T> persis
471464
}
472465

473466
private <T> Criteria createMatchingVersionCriteria(T entity, RelationalPersistentEntity<T> persistentEntity) {
467+
474468
PersistentPropertyAccessor<?> propertyAccessor = persistentEntity.getPropertyAccessor(entity);
475469
RelationalPersistentProperty versionProperty = persistentEntity.getVersionProperty();
476470

src/test/java/org/springframework/data/r2dbc/repository/support/AbstractSimpleR2dbcRepositoryIntegrationTests.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public void shouldSaveNewObject() {
119119
assertThat(map).containsEntry("name", "SCHAUFELRADBAGGER").containsEntry("manual", 12).containsKey("id");
120120
}
121121

122-
@Test
122+
@Test // gh-93
123123
public void shouldSaveNewObjectAndSetVersionIfWrapperVersionPropertyExists() {
124124

125125
LegoSetVersionable legoSet = new LegoSetVersionable(null, "SCHAUFELRADBAGGER", 12, null);
@@ -137,10 +137,10 @@ public void shouldSaveNewObjectAndSetVersionIfWrapperVersionPropertyExists() {
137137
.containsKey("id");
138138
}
139139

140-
@Test
140+
@Test // gh-93
141141
public void shouldSaveNewObjectAndSetVersionIfPrimitiveVersionPropertyExists() {
142142

143-
LegoSetPrimitiveVersionable legoSet = new LegoSetPrimitiveVersionable(null, "SCHAUFELRADBAGGER", 12, -1);
143+
LegoSetPrimitiveVersionable legoSet = new LegoSetPrimitiveVersionable(null, "SCHAUFELRADBAGGER", 12, 0);
144144

145145
repository.save(legoSet) //
146146
.as(StepVerifier::create) //
@@ -173,7 +173,7 @@ public void shouldUpdateObject() {
173173
assertThat(map).containsEntry("name", "SCHAUFELRADBAGGER").containsEntry("manual", 14).containsKey("id");
174174
}
175175

176-
@Test
176+
@Test // gh-93
177177
public void shouldUpdateVersionableObjectAndIncreaseVersion() {
178178

179179
jdbc.execute("INSERT INTO legoset (name, manual, version) VALUES('SCHAUFELRADBAGGER', 12, 42)");
@@ -197,7 +197,7 @@ public void shouldUpdateVersionableObjectAndIncreaseVersion() {
197197
.containsKey("id");
198198
}
199199

200-
@Test
200+
@Test // gh-93
201201
public void shouldFailWithOptimistickLockingWhenVersionDoesNotMatchOnUpdate() {
202202

203203
jdbc.execute("INSERT INTO legoset (name, manual, version) VALUES('SCHAUFELRADBAGGER', 12, 42)");

0 commit comments

Comments
 (0)