diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java index 88aec8b7b..91a85875b 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java @@ -415,9 +415,7 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations { // 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; + long newVersion = (previousVersion == null ? 0 : previousVersion.longValue()) + 1; preparedInstance = RelationalEntityVersionUtils.setVersionNumberOnEntity(instance, newVersion, persistentEntity, converter); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java index 219448fe0..497ecca7b 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java @@ -54,6 +54,7 @@ import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.ReadOnlyProperty; import org.springframework.data.annotation.Version; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Persistable; import org.springframework.data.domain.Sort; import org.springframework.data.jdbc.core.convert.DataAccessStrategy; import org.springframework.data.jdbc.core.convert.JdbcConverter; @@ -278,7 +279,8 @@ class JdbcAggregateTemplateIntegrationTests { template.save(createLegoSet("Star")); template.save(createLegoSet("Frozen")); - final Sort sort = Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST)); + final Sort sort = + Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST)); Iterable reloadedLegoSets = template.findAll(LegoSet.class, sort); assertThat(reloadedLegoSets) // @@ -923,6 +925,16 @@ class JdbcAggregateTemplateIntegrationTests { saveAndUpdateAggregateWithPrimitiveVersion(new AggregateWithPrimitiveShortVersion(), Number::shortValue); } + @Test // GH-1254 + void saveAndUpdateAggregateWithIdAndNullVersion() { + + PersistableVersionedAggregate aggregate = new PersistableVersionedAggregate(); + aggregate.setVersion(null); + aggregate.setId(23L); + + assertThatThrownBy(() -> template.save(aggregate)).isInstanceOf(DbActionExecutionException.class); + } + @Test // DATAJDBC-462 @EnabledOnFeature(SUPPORTS_QUOTED_IDS) void resavingAnUnversionedEntity() { @@ -1115,18 +1127,15 @@ class JdbcAggregateTemplateIntegrationTests { @Column("id4") @Id private Long id; String name; - @MappedCollection(idColumn = "LIST_PARENT") - List content = new ArrayList<>(); + @MappedCollection(idColumn = "LIST_PARENT") List content = new ArrayList<>(); } @Table("LIST_PARENT") static class ListParentAllArgs { - @Column("id4") @Id - private final Long id; + @Column("id4") @Id private final Long id; private final String name; - @MappedCollection(idColumn = "LIST_PARENT") - private final List content = new ArrayList<>(); + @MappedCollection(idColumn = "LIST_PARENT") private final List content = new ArrayList<>(); @PersistenceConstructor ListParentAllArgs(Long id, String name, List content) { @@ -1287,6 +1296,20 @@ class JdbcAggregateTemplateIntegrationTests { abstract void setVersion(Number newVersion); } + @Data + @Table("VERSIONED_AGGREGATE") + static class PersistableVersionedAggregate implements Persistable { + + @Id private Long id; + + @Version Long version; + + @Override + public boolean isNew() { + return getId() == null; + } + } + @Value @With @Table("VERSIONED_AGGREGATE")