From ae7cb66e3fe3fc499ee4722f66e6358d6e2bc345 Mon Sep 17 00:00:00 2001 From: Mateusz Chrzonstowski Date: Fri, 23 Aug 2024 03:58:25 +0200 Subject: [PATCH] Ensure version update happens in transaction with insert. Original pull request #687 --- .../PartyHatRepositoryImpl.java | 2 ++ .../SelectiveUpdateApplication.java | 1 - .../SelectiveUpdateApplicationTests.java | 21 ++++++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/jdbc/howto/selectiveupdate/src/main/java/example.springdata/jdbc/howto/selectiveupdate/PartyHatRepositoryImpl.java b/jdbc/howto/selectiveupdate/src/main/java/example.springdata/jdbc/howto/selectiveupdate/PartyHatRepositoryImpl.java index 3513338f6..b0f822c50 100644 --- a/jdbc/howto/selectiveupdate/src/main/java/example.springdata/jdbc/howto/selectiveupdate/PartyHatRepositoryImpl.java +++ b/jdbc/howto/selectiveupdate/src/main/java/example.springdata/jdbc/howto/selectiveupdate/PartyHatRepositoryImpl.java @@ -17,6 +17,7 @@ import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; +import org.springframework.transaction.annotation.Transactional; import java.util.HashMap; import java.util.Map; @@ -35,6 +36,7 @@ public PartyHatRepositoryImpl(NamedParameterJdbcOperations template) { this.template = template; } + @Transactional @Override public void addPartyHat(Minion minion) { diff --git a/jdbc/howto/selectiveupdate/src/main/java/example.springdata/jdbc/howto/selectiveupdate/SelectiveUpdateApplication.java b/jdbc/howto/selectiveupdate/src/main/java/example.springdata/jdbc/howto/selectiveupdate/SelectiveUpdateApplication.java index 9e1b01dd8..d1e005f01 100644 --- a/jdbc/howto/selectiveupdate/src/main/java/example.springdata/jdbc/howto/selectiveupdate/SelectiveUpdateApplication.java +++ b/jdbc/howto/selectiveupdate/src/main/java/example.springdata/jdbc/howto/selectiveupdate/SelectiveUpdateApplication.java @@ -17,7 +17,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication class SelectiveUpdateApplication { diff --git a/jdbc/howto/selectiveupdate/src/test/java/example/springdata/jdbc/howto/selectiveupdate/SelectiveUpdateApplicationTests.java b/jdbc/howto/selectiveupdate/src/test/java/example/springdata/jdbc/howto/selectiveupdate/SelectiveUpdateApplicationTests.java index 5d6943496..041679138 100644 --- a/jdbc/howto/selectiveupdate/src/test/java/example/springdata/jdbc/howto/selectiveupdate/SelectiveUpdateApplicationTests.java +++ b/jdbc/howto/selectiveupdate/src/test/java/example/springdata/jdbc/howto/selectiveupdate/SelectiveUpdateApplicationTests.java @@ -58,7 +58,7 @@ void turnPurpleByDirectUpdate() { Minion bob2 = minions.findById(bob.id).orElseThrow(); - assertThat(bob2.toys).containsExactly(bob.toys.toArray(new Toy[] {})); + assertThat(bob2.toys).containsExactlyElementsOf(bob.toys); assertThat(bob2.name).isEqualTo("Bob"); assertThat(bob2.color).isEqualTo(Color.PURPLE); } @@ -81,4 +81,23 @@ void grantPartyHat() { assertThatExceptionOfType(OptimisticLockingFailureException.class).isThrownBy(() -> minions.addPartyHat(bob)); } + @Test + void cannotGrantPartyHatWhenOutOfSync() { + + Minion bob = new Minion("Bob").addToy(new Toy("Tiger Duck")).addToy(new Toy("Security blanket")); + minions.save(bob); + minions.turnPurple(bob.id); + + assertThat(bob.color).isEqualTo(Color.YELLOW); + assertThat(bob.version).isOne(); + assertThatExceptionOfType(OptimisticLockingFailureException.class).isThrownBy(() -> minions.addPartyHat(bob)); + + Minion bob2 = minions.findById(bob.id).orElseThrow(); + + assertThat(bob2.name).isEqualTo("Bob"); + assertThat(bob2.color).isEqualTo(Color.PURPLE); + assertThat(bob2.version).isEqualTo(bob.version + 1); + assertThat(bob2.toys).extracting("name").containsExactlyInAnyOrder("Tiger Duck", "Security blanket"); + } + }