From 4b56b5f2b28f849fe30de704e1f68cd907efac19 Mon Sep 17 00:00:00 2001 From: Biju Kunjummen Date: Sat, 24 Dec 2022 15:10:08 -0800 Subject: [PATCH 1/7] Changes conditional for Spanner and Datastore Transaction Manager Conditional for Spanner is based on missing beans of type SpannerTransactionManager instead of PlatformTransactionManager, this way it always gets created if Spanner libs are pulled in Conditional for Datastore is based on missing beans of type DatastoreTransactionManager instead of PlatformTransactionManager, this way it gets created if Datastore libs are pulled in It is user responsibility to designate the transaction's right transaction manager: ``` @Transactional(transactionManager = "spannerTransactionManager") ``` ``` @Transactional(transactionManager = "datastoreTransactionManager") ``` --- .../DatastoreTransactionManagerAutoConfiguration.java | 3 +-- .../spanner/SpannerTransactionManagerAutoConfiguration.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/spring-cloud-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/datastore/DatastoreTransactionManagerAutoConfiguration.java b/spring-cloud-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/datastore/DatastoreTransactionManagerAutoConfiguration.java index 41d1c980c9..4935684d27 100644 --- a/spring-cloud-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/datastore/DatastoreTransactionManagerAutoConfiguration.java +++ b/spring-cloud-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/datastore/DatastoreTransactionManagerAutoConfiguration.java @@ -26,7 +26,6 @@ import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.transaction.PlatformTransactionManager; /** * Auto-configuration for {@link DatastoreTransactionManager}. @@ -55,7 +54,7 @@ static class DatastoreTransactionManagerConfiguration { } @Bean - @ConditionalOnMissingBean(PlatformTransactionManager.class) + @ConditionalOnMissingBean public DatastoreTransactionManager datastoreTransactionManager() { DatastoreTransactionManager transactionManager = new DatastoreTransactionManager(this.datastore); diff --git a/spring-cloud-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/spanner/SpannerTransactionManagerAutoConfiguration.java b/spring-cloud-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/spanner/SpannerTransactionManagerAutoConfiguration.java index a38e3a0b5b..52d80fb8e1 100644 --- a/spring-cloud-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/spanner/SpannerTransactionManagerAutoConfiguration.java +++ b/spring-cloud-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/spanner/SpannerTransactionManagerAutoConfiguration.java @@ -28,7 +28,6 @@ import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.transaction.PlatformTransactionManager; /** * Auto-configuration for {@link SpannerTransactionManager}. @@ -57,7 +56,7 @@ static class DatabaseClientTransactionManagerConfiguration { } @Bean - @ConditionalOnMissingBean(PlatformTransactionManager.class) + @ConditionalOnMissingBean public SpannerTransactionManager spannerTransactionManager() { SpannerTransactionManager transactionManager = new SpannerTransactionManager(this.databaseClientProvider); From 1dd15bf2164815b69c3129f88fc90a986561ce43 Mon Sep 17 00:00:00 2001 From: Biju Kunjummen Date: Tue, 2 May 2023 20:48:35 -0700 Subject: [PATCH 2/7] Adds information about disambiguating the right transaction manager bean --- docs/src/main/asciidoc/datastore.adoc | 7 +++++++ docs/src/main/asciidoc/spanner.adoc | 8 ++++++++ docs/src/main/md/datastore.md | 10 ++++++++++ docs/src/main/md/spanner.md | 9 +++++++++ 4 files changed, 34 insertions(+) diff --git a/docs/src/main/asciidoc/datastore.adoc b/docs/src/main/asciidoc/datastore.adoc index 9d34d63328..842c429a2a 100644 --- a/docs/src/main/asciidoc/datastore.adoc +++ b/docs/src/main/asciidoc/datastore.adoc @@ -854,6 +854,13 @@ This feature requires a bean of `DatastoreTransactionManager`, which is provided If a method annotated with `@Transactional` calls another method also annotated, then both methods will work within the same transaction. `performTransaction` cannot be used in `@Transactional` annotated methods because Cloud Datastore does not support transactions within transactions. +Other Google Cloud database related libraries like spanner, firestore can introduce `PlatformTransactionManager` beans, and can interfere with Datastore Transaction Manager. To disambiguate, explicitly specify the name of the transaction manager bean for such `@Transactional` methods, for eg. + +[source,java] +---- +@Transactional(transactionManager = "datastoreTransactionManager") +---- + ==== Read-Write Support for Maps You can work with Maps of type `Map` instead of with entity objects by directly reading and writing them to and from Cloud Datastore. diff --git a/docs/src/main/asciidoc/spanner.adoc b/docs/src/main/asciidoc/spanner.adoc index 76330e057d..6d6b53238e 100644 --- a/docs/src/main/asciidoc/spanner.adoc +++ b/docs/src/main/asciidoc/spanner.adoc @@ -956,6 +956,14 @@ This feature requires a bean of `SpannerTransactionManager`, which is provided w If a method annotated with `@Transactional` calls another method also annotated, then both methods will work within the same transaction. `performReadOnlyTransaction` and `performReadWriteTransaction` cannot be used in `@Transactional` annotated methods because Cloud Spanner does not support transactions within transactions. +Other Google Cloud database related libraries like datastore, firestore can introduce `PlatformTransactionManager` beans, and can interfere with Spanner Transaction Manager. To disambiguate, explicitly specify the name of the transaction manager bean for such `@Transactional` methods, for eg. + +[source,java] +---- +@Transactional(transactionManager = "spannerTransactionManager") +---- + + ==== DML Statements `SpannerTemplate` supports https://cloud.google.com/spanner/docs/dml-tasks:[DML] `Statements`. diff --git a/docs/src/main/md/datastore.md b/docs/src/main/md/datastore.md index e106a56499..1ede908c20 100644 --- a/docs/src/main/md/datastore.md +++ b/docs/src/main/md/datastore.md @@ -944,6 +944,16 @@ same transaction. `performTransaction` cannot be used in `@Transactional` annotated methods because Cloud Datastore does not support transactions within transactions. +Other Google Cloud database related libraries like spanner, firestore +can introduce `PlatformTransactionManager` beans, and can interfere +with Datastore Transaction Manager. +To disambiguate, explicitly specify the name of the transaction manager +bean for such `@Transactional` methods, for eg. + +```java +@Transactional(transactionManager = "datastoreTransactionManager") +``` + #### Read-Write Support for Maps You can work with Maps of type `Map` instead of with entity diff --git a/docs/src/main/md/spanner.md b/docs/src/main/md/spanner.md index 54bee11e4e..b61dfaf9d0 100644 --- a/docs/src/main/md/spanner.md +++ b/docs/src/main/md/spanner.md @@ -1123,6 +1123,15 @@ same transaction. `performReadOnlyTransaction` and annotated methods because Cloud Spanner does not support transactions within transactions. +Other Google Cloud database related libraries like datastore, firestore +can introduce `PlatformTransactionManager` beans, and can interfere with +Spanner Transaction Manager. To disambiguate, explicitly specify the name of +transaction manager bean for such `@Transactional` methods, for eg. + +```java +@Transactional(transactionManager = "spannerTransactionManager") +``` + #### DML Statements `SpannerTemplate` supports From 0b13809bea74418fa4c83fdbd57aa89f2fdc7f8c Mon Sep 17 00:00:00 2001 From: Biju Kunjummen Date: Mon, 8 May 2023 19:39:28 -0700 Subject: [PATCH 3/7] Adds in sample to demonstrate using the relevant transaction managers --- .../example/MultipleDataModuleExample.java | 24 +++++------ .../main/java/com/example/PersonService.java | 43 +++++++++++++++++++ .../main/java/com/example/TraderService.java | 43 +++++++++++++++++++ 3 files changed, 98 insertions(+), 12 deletions(-) create mode 100644 spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/PersonService.java create mode 100644 spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/TraderService.java diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/MultipleDataModuleExample.java b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/MultipleDataModuleExample.java index ad67396310..26da215523 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/MultipleDataModuleExample.java +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/MultipleDataModuleExample.java @@ -26,11 +26,11 @@ @SpringBootApplication public class MultipleDataModuleExample { - // A Spring Data Datastore repository - @Autowired PersonRepository personRepository; + // Internally uses a Spring Data Datastore repository + @Autowired private PersonService personService; - // A Spring Data Cloud Spanner repository - @Autowired TraderRepository traderRepository; + // Internally uses a Spring Data Cloud Spanner repository + @Autowired private TraderService traderService; public static void main(String[] args) { SpringApplication.run(MultipleDataModuleExample.class, args); @@ -41,19 +41,19 @@ ApplicationRunner applicationRunner() { return args -> { System.out.println("Deleting all entities."); - this.personRepository.deleteAll(); - this.traderRepository.deleteAll(); + this.personService.deleteAll(); + this.traderService.deleteAll(); - System.out.println("The number of Person entities is now: " + this.personRepository.count()); - System.out.println("The number of Trader entities is now: " + this.traderRepository.count()); + System.out.println("The number of Person entities is now: " + this.personService.count()); + System.out.println("The number of Trader entities is now: " + this.traderService.count()); System.out.println("Saving one entity with each repository."); - this.traderRepository.save(new Trader("id1", "trader", "one")); - this.personRepository.save(new Person(1L, "person1")); + this.traderService.save(new Trader("id1", "trader", "one")); + this.personService.save(new Person(1L, "person1")); - System.out.println("The number of Person entities is now: " + this.personRepository.count()); - System.out.println("The number of Trader entities is now: " + this.traderRepository.count()); + System.out.println("The number of Person entities is now: " + this.personService.count()); + System.out.println("The number of Trader entities is now: " + this.traderService.count()); }; } } diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/PersonService.java b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/PersonService.java new file mode 100644 index 0000000000..26a274c56d --- /dev/null +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/PersonService.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(transactionManager = "spannerTransactionManager") +public class PersonService { + + private final PersonRepository personRepository; + + public PersonService(PersonRepository personRepository) { + this.personRepository = personRepository; + } + + public Person save(Person person) { + return this.personRepository.save(person); + } + + public void deleteAll() { + this.personRepository.deleteAll(); + } + + public Long count() { + return this.personRepository.count(); + } +} diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/TraderService.java b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/TraderService.java new file mode 100644 index 0000000000..56657a229d --- /dev/null +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/TraderService.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(transactionManager = "datastoreTransactionManager") +public class TraderService { + + private final TraderRepository traderRepository; + + public TraderService(TraderRepository traderRepository) { + this.traderRepository = traderRepository; + } + + public Trader save(Trader trader) { + return this.traderRepository.save(trader); + } + + public void deleteAll() { + this.traderRepository.deleteAll(); + } + + public Long count() { + return this.traderRepository.count(); + } +} From 3fdb5ea6e2657876d443f0c593de35e4cd271deb Mon Sep 17 00:00:00 2001 From: Biju Kunjummen Date: Tue, 9 May 2023 18:32:25 -0700 Subject: [PATCH 4/7] Fixes license header --- .../src/main/java/com/example/PersonService.java | 2 +- .../src/main/java/com/example/TraderService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/PersonService.java b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/PersonService.java index 26a274c56d..067a969d13 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/PersonService.java +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/PersonService.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 the original author or authors. + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/TraderService.java b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/TraderService.java index 56657a229d..9cdc35fd35 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/TraderService.java +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/main/java/com/example/TraderService.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 the original author or authors. + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From da4a86ae9636f5a828f32f4a14d2028fbb8a1af1 Mon Sep 17 00:00:00 2001 From: Biju Kunjummen Date: Tue, 9 May 2023 18:34:02 -0700 Subject: [PATCH 5/7] Adds readme about transactions with multi-module --- .../spring-cloud-gcp-data-multi-sample/README.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/README.adoc b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/README.adoc index 7cec965901..64cec327f5 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/README.adoc +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/README.adoc @@ -1,6 +1,7 @@ = Spring Framework on Google Cloud Cloud Spanner and Datastore Combined Usage Example This code sample demonstrates how to use both link:../../spring-cloud-gcp-starters/spring-cloud-gcp-starter-data-spanner[Spring Data Cloud Spanner] and link:../../spring-cloud-gcp-starters/spring-cloud-gcp-starter-data-datastore[Spring Data Cloud Datastore] using the Spring Data Cloud Datastore modules in a single Spring application. +This sample also demonstrates usage of transactions with both modules. == Running the example From e531920d633b1c4844a8eca1331679ade548a02e Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Fri, 12 May 2023 21:56:22 -0400 Subject: [PATCH 6/7] fix: additional sample test for both transactionManager work together. --- ...eDataModuleTransactionIntegrationTest.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleTransactionIntegrationTest.java diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleTransactionIntegrationTest.java b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleTransactionIntegrationTest.java new file mode 100644 index 0000000000..f975817c5a --- /dev/null +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleTransactionIntegrationTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIfSystemProperty; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +/** Tests that our Spring Data modules can be used with each other with transaction manager. */ +// Please use "-Dit.multisample=true" to enable the tests +@ExtendWith(SpringExtension.class) +@EnabledIfSystemProperty(named = "it.multisample", matches = "true") +@TestPropertySource("classpath:application-test.properties") +@SpringBootTest +class MultipleDataModuleTransactionIntegrationTest { + + @Autowired TraderService traderService; + + @Autowired PersonService personService; + + @Test + void testMultipleModulesTogether() { + + this.traderService.deleteAll(); + this.personService.deleteAll(); + + assertThat(this.traderService.count()).isZero(); + assertThat(this.personService.count()).isZero(); + + this.traderService.save(new Trader("id1", "trader", "one")); + this.personService.save(new Person(1L, "person1")); + + assertThat(this.traderService.count()).isEqualTo(1L); + assertThat(this.personService.count()).isEqualTo(1L); + } +} From 1b5680ceb931bff757660b73329c7843fe03fcf6 Mon Sep 17 00:00:00 2001 From: Min Zhu Date: Mon, 15 May 2023 09:27:51 -0400 Subject: [PATCH 7/7] fix: remove added new test class and move transactional test together with repo test. --- .../MultipleDataModuleIntegrationTest.java | 23 +++++++- ...eDataModuleTransactionIntegrationTest.java | 56 ------------------- 2 files changed, 22 insertions(+), 57 deletions(-) delete mode 100644 spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleTransactionIntegrationTest.java diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleIntegrationTest.java b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleIntegrationTest.java index ddc6f71ae5..d8ff90cbfa 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleIntegrationTest.java +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleIntegrationTest.java @@ -23,6 +23,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -31,7 +32,7 @@ @ExtendWith(SpringExtension.class) @EnabledIfSystemProperty(named = "it.multisample", matches = "true") @TestPropertySource("classpath:application-test.properties") -@EnableAutoConfiguration +@SpringBootTest class MultipleDataModuleIntegrationTest { // The Spanner Repo @@ -40,6 +41,10 @@ class MultipleDataModuleIntegrationTest { // The Datastore Repo @Autowired PersonRepository datastorePersonRepository; + @Autowired TraderService traderService; + + @Autowired PersonService personService; + @Test void testMultipleModulesTogether() { @@ -55,4 +60,20 @@ void testMultipleModulesTogether() { assertThat(this.traderRepository.count()).isEqualTo(1L); assertThat(this.datastorePersonRepository.count()).isEqualTo(1L); } + + @Test + void testMultipleModulesTogetherWithTransaction() { + + this.traderService.deleteAll(); + this.personService.deleteAll(); + + assertThat(this.traderService.count()).isZero(); + assertThat(this.personService.count()).isZero(); + + this.traderService.save(new Trader("id1", "trader", "one")); + this.personService.save(new Person(1L, "person1")); + + assertThat(this.traderService.count()).isEqualTo(1L); + assertThat(this.personService.count()).isEqualTo(1L); + } } diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleTransactionIntegrationTest.java b/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleTransactionIntegrationTest.java deleted file mode 100644 index f975817c5a..0000000000 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-data-multi-sample/src/test/java/com/example/MultipleDataModuleTransactionIntegrationTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2023 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIfSystemProperty; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -/** Tests that our Spring Data modules can be used with each other with transaction manager. */ -// Please use "-Dit.multisample=true" to enable the tests -@ExtendWith(SpringExtension.class) -@EnabledIfSystemProperty(named = "it.multisample", matches = "true") -@TestPropertySource("classpath:application-test.properties") -@SpringBootTest -class MultipleDataModuleTransactionIntegrationTest { - - @Autowired TraderService traderService; - - @Autowired PersonService personService; - - @Test - void testMultipleModulesTogether() { - - this.traderService.deleteAll(); - this.personService.deleteAll(); - - assertThat(this.traderService.count()).isZero(); - assertThat(this.personService.count()).isZero(); - - this.traderService.save(new Trader("id1", "trader", "one")); - this.personService.save(new Person(1L, "person1")); - - assertThat(this.traderService.count()).isEqualTo(1L); - assertThat(this.personService.count()).isEqualTo(1L); - } -}