Dedicated exception for aggregate roots without id property.

We now distinguish between an id not set during insert and a supposed aggregate root without id property.

Closes #1502
Original pull request #1855
This commit is contained in:
Jens Schauder
2024-08-13 10:56:18 +02:00
parent bec76278ff
commit 51d20f2c06
2 changed files with 47 additions and 0 deletions

View File

@@ -165,6 +165,8 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
Assert.notNull(instance, "Aggregate instance must not be null");
verifyIdProperty(instance);
return performSave(new EntityAndChangeCreator<>(instance, changeCreatorSelectorForSave(instance)));
}
@@ -179,6 +181,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
List<EntityAndChangeCreator<T>> entityAndChangeCreators = new ArrayList<>();
for (T instance : instances) {
verifyIdProperty(instance);
entityAndChangeCreators.add(new EntityAndChangeCreator<>(instance, changeCreatorSelectorForSave(instance)));
}
return performSaveAll(entityAndChangeCreators);
@@ -425,6 +428,11 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
}
}
private <T> void verifyIdProperty(T instance) {
// accessing the id property just to raise an exception in the case it does not exist.
context.getRequiredPersistentEntity(instance.getClass()).getRequiredIdProperty();
}
private <T> void doDeleteAll(Iterable<? extends T> instances, Class<T> domainType) {
BatchingAggregateChange<T, DeleteAggregateChange<T>> batchingAggregateChange = BatchingAggregateChange

View File

@@ -32,10 +32,12 @@ 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.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.Identifier;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.convert.MappingJdbcConverter;
import org.springframework.data.jdbc.core.convert.RelationResolver;
import org.springframework.data.mapping.callback.EntityCallbacks;
import org.springframework.data.relational.core.conversion.IdValueSource;
import org.springframework.data.relational.core.conversion.MutableAggregateChange;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
@@ -46,6 +48,8 @@ import org.springframework.data.relational.core.mapping.event.BeforeConvertCallb
import org.springframework.data.relational.core.mapping.event.BeforeDeleteCallback;
import org.springframework.data.relational.core.mapping.event.BeforeSaveCallback;
import java.util.List;
/**
* Unit tests for {@link JdbcAggregateTemplate}.
*
@@ -333,6 +337,38 @@ public class JdbcAggregateTemplateUnitTests {
template.deleteAllById(emptyList(), SampleEntity.class);
}
@Test // GH-1502
void saveThrowsExceptionWhenIdIsNotSet() {
SampleEntity alfred = new SampleEntity(null, "Alfred");
when(callbacks.callback(any(), any(), any(Object[].class))).thenReturn(alfred);
when(dataAccessStrategy.insert(eq(alfred), any(Class.class), any(Identifier.class), any(IdValueSource.class)))
.thenReturn(null);
assertThatIllegalArgumentException().isThrownBy(() -> template.save(alfred))
.withMessage("After saving the identifier must not be null");
}
@Test // GH-1502
void saveThrowsExceptionWhenIdDoesNotExist() {
NoIdEntity alfred = new NoIdEntity("Alfred");
assertThatIllegalStateException().isThrownBy(() -> template.save(alfred))
.withMessage("Required identifier property not found for class %s".formatted(NoIdEntity.class.getName()));
}
@Test // GH-1502
void saveThrowsExceptionWhenIdDoesNotExistOnSaveAll() {
NoIdEntity alfred = new NoIdEntity("Alfred");
NoIdEntity berta = new NoIdEntity("Berta");
assertThatIllegalStateException().isThrownBy(() -> template.saveAll( List.of(alfred, berta)))
.withMessage("Required identifier property not found for class %s".formatted(NoIdEntity.class.getName()));
}
private static class SampleEntity {
@Column("id1")
@@ -451,4 +487,7 @@ public class JdbcAggregateTemplateUnitTests {
return this.version;
}
}
record NoIdEntity(String name) {
}
}