From f6432092fa89615941767af850419b2680c447c5 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 21 Aug 2018 12:04:44 +0200 Subject: [PATCH] #395 - Correcting handling of immutable properties. If properties are final they need to have a matching argument in the persistence constructor or a matching "Wither". Otherwise trying to set them results in an exception. --- .../springdata/jdbc/basics/aggregate/LegoSet.java | 11 +++++++++-- .../springdata/jdbc/basics/aggregate/Model.java | 3 +++ .../springdata/jdbc/basics/aggregate/ModelReport.java | 3 +++ .../springdata/jdbc/basics/simpleentity/Category.java | 10 ++++++++-- .../jdbc/basics/simpleentity/SimpleEntityTests.java | 7 ++----- .../java/example/springdata/jdbc/mybatis/LegoSet.java | 3 +-- jdbc/pom.xml | 4 ++-- 7 files changed, 28 insertions(+), 13 deletions(-) diff --git a/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/LegoSet.java b/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/LegoSet.java index bbde4d82..222d30a9 100644 --- a/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/LegoSet.java +++ b/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/LegoSet.java @@ -15,7 +15,10 @@ */ package example.springdata.jdbc.basics.aggregate; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.experimental.Wither; import java.time.Period; import java.time.temporal.ChronoUnit; @@ -34,6 +37,7 @@ import org.springframework.data.annotation.Transient; */ @Data @AccessType(Type.PROPERTY) +@AllArgsConstructor(access = AccessLevel.PACKAGE) public class LegoSet { private @Id int id; @@ -47,8 +51,11 @@ public class LegoSet { private Manual manual; // You can build multiple models from one LegoSet - @AccessType(Type.FIELD) - private final Map models = new HashMap<>(); + private final @AccessType(Type.FIELD) @Wither(AccessLevel.PACKAGE) Map models; + + LegoSet() { + this.models = new HashMap<>(); + } // conversion for custom types currently has to be done through getters/setter + marking the underlying property with // @Transient. diff --git a/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/Model.java b/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/Model.java index 2a723680..42ce9a53 100644 --- a/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/Model.java +++ b/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/Model.java @@ -15,7 +15,9 @@ */ package example.springdata.jdbc.basics.aggregate; +import lombok.AccessLevel; import lombok.Value; +import lombok.experimental.Wither; /** * One of potentially multiple models that can be build from a single {@link LegoSet}. No getters or setters needed. @@ -23,6 +25,7 @@ import lombok.Value; * @author Jens Schauder */ @Value +@Wither(AccessLevel.PACKAGE) public class Model { String name, description; } diff --git a/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/ModelReport.java b/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/ModelReport.java index d0a30f65..08dc2b45 100644 --- a/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/ModelReport.java +++ b/jdbc/basics/src/main/java/example/springdata/jdbc/basics/aggregate/ModelReport.java @@ -15,12 +15,15 @@ */ package example.springdata.jdbc.basics.aggregate; +import lombok.AccessLevel; import lombok.Value; +import lombok.experimental.Wither; /** * @author Jens Schauder */ @Value +@Wither(AccessLevel.PACKAGE) public class ModelReport { String modelName, description, setName; } diff --git a/jdbc/basics/src/main/java/example/springdata/jdbc/basics/simpleentity/Category.java b/jdbc/basics/src/main/java/example/springdata/jdbc/basics/simpleentity/Category.java index d2f8c64b..12cb146d 100644 --- a/jdbc/basics/src/main/java/example/springdata/jdbc/basics/simpleentity/Category.java +++ b/jdbc/basics/src/main/java/example/springdata/jdbc/basics/simpleentity/Category.java @@ -17,12 +17,16 @@ package example.springdata.jdbc.basics.simpleentity; import example.springdata.jdbc.basics.aggregate.AgeGroup; import example.springdata.jdbc.basics.aggregate.LegoSet; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Data; import lombok.Setter; +import lombok.experimental.Wither; import java.time.LocalDateTime; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.PersistenceConstructor; /** * Coarse classification for {@link LegoSet}s, like "Car", "Plane", "Building" and so on. @@ -30,11 +34,12 @@ import org.springframework.data.annotation.Id; * @author Jens Schauder */ @Data +@AllArgsConstructor(access = AccessLevel.PRIVATE, onConstructor = @__(@PersistenceConstructor)) public class Category { - private final @Id Long id; + private final @Id @Wither Long id; private String name, description; - private LocalDateTime created = LocalDateTime.now(); + private LocalDateTime created; private @Setter long inserted; private AgeGroup ageGroup; @@ -44,6 +49,7 @@ public class Category { this.name = name; this.description = description; this.ageGroup = ageGroup; + this.created = LocalDateTime.now(); } public void timeStamp() { diff --git a/jdbc/basics/src/test/java/example/springdata/jdbc/basics/simpleentity/SimpleEntityTests.java b/jdbc/basics/src/test/java/example/springdata/jdbc/basics/simpleentity/SimpleEntityTests.java index a5c41f71..d2b69841 100644 --- a/jdbc/basics/src/test/java/example/springdata/jdbc/basics/simpleentity/SimpleEntityTests.java +++ b/jdbc/basics/src/test/java/example/springdata/jdbc/basics/simpleentity/SimpleEntityTests.java @@ -15,7 +15,6 @@ */ package example.springdata.jdbc.basics.simpleentity; -import static java.util.Arrays.*; import static org.assertj.core.api.Assertions.*; import example.springdata.jdbc.basics.Output; @@ -44,12 +43,10 @@ public class SimpleEntityTests { public void exerciseRepositoryForSimpleEntity() { // create some categories - Category cars = new Category("Cars", "Anything that has approximately 4 wheels", AgeGroup._3to8); - - Category buildings = new Category("Buildings", null, AgeGroup._12andOlder); + Category cars = repository.save(new Category("Cars", "Anything that has approximately 4 wheels", AgeGroup._3to8)); + Category buildings = repository.save(new Category("Buildings", null, AgeGroup._12andOlder)); // save categories - repository.saveAll(asList(cars, buildings)); Output.list(repository.findAll(), "`Cars` and `Buildings` got saved"); assertThat(cars.getId()).isNotNull(); diff --git a/jdbc/mybatis/src/main/java/example/springdata/jdbc/mybatis/LegoSet.java b/jdbc/mybatis/src/main/java/example/springdata/jdbc/mybatis/LegoSet.java index c77a0fc8..e8ab33f6 100644 --- a/jdbc/mybatis/src/main/java/example/springdata/jdbc/mybatis/LegoSet.java +++ b/jdbc/mybatis/src/main/java/example/springdata/jdbc/mybatis/LegoSet.java @@ -30,8 +30,7 @@ import org.springframework.data.annotation.Id; @Data public class LegoSet { - // You can build multiple models from one LegoSet - private final Map models = new HashMap<>(); + private Map models = new HashMap<>(); private @Id Integer id; private String name; diff --git a/jdbc/pom.xml b/jdbc/pom.xml index e5a5d1cb..c973a673 100644 --- a/jdbc/pom.xml +++ b/jdbc/pom.xml @@ -24,7 +24,7 @@ - Lovelace-RC2 + Lovelace-BUILD-SNAPSHOT @@ -34,7 +34,7 @@ spring-data-next - Lovelace-RC2 + Lovelace-BUILD-SNAPSHOT