diff --git a/.local-db/todos.mv.db b/.local-db/todos.mv.db new file mode 100644 index 0000000000..c081aa5aad Binary files /dev/null and b/.local-db/todos.mv.db differ diff --git a/.local-db/topics.mv.db b/.local-db/topics.mv.db new file mode 100644 index 0000000000..204bc60d70 Binary files /dev/null and b/.local-db/topics.mv.db differ diff --git a/persistence-modules/spring-data-jdbc/pom.xml b/persistence-modules/spring-data-jdbc/pom.xml index 2b4c6d21aa..168b171337 100644 --- a/persistence-modules/spring-data-jdbc/pom.xml +++ b/persistence-modules/spring-data-jdbc/pom.xml @@ -21,11 +21,19 @@ org.springframework.boot spring-boot-starter-data-jdbc + + org.springframework.boot + spring-boot-starter-data-jpa + com.h2database h2 runtime + + org.springframework.boot + spring-boot-starter-test + - \ No newline at end of file + diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/Application.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/Application.java index 8fff82de32..a808a3daea 100644 --- a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/Application.java +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/Application.java @@ -1,17 +1,16 @@ package com.baeldung.springdatajdbcintro; -import java.util.Optional; - +import ch.qos.logback.classic.Logger; +import com.baeldung.springdatajdbcintro.entity.Person; +import com.baeldung.springdatajdbcintro.repository.PersonRepository; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.core.env.AbstractEnvironment; -import com.baeldung.springdatajdbcintro.entity.Person; -import com.baeldung.springdatajdbcintro.repository.PersonRepository; - -import ch.qos.logback.classic.Logger; +import java.util.Optional; @SpringBootApplication public class Application implements CommandLineRunner { @@ -24,6 +23,7 @@ public class Application implements CommandLineRunner { private DatabaseSeeder dbSeeder; public static void main(String[] args) { + System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "jdbcintro"); SpringApplication.run(Application.class, args); } diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/entity/Person.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/entity/Person.java index 7c4c1eec73..ac2c329e08 100644 --- a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/entity/Person.java +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/entity/Person.java @@ -1,7 +1,9 @@ package com.baeldung.springdatajdbcintro.entity; import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Table; +@Table public class Person { @Id diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/repository/PersonRepository.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/repository/PersonRepository.java index b2f026fa0c..ceb7a968a4 100644 --- a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/repository/PersonRepository.java +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springdatajdbcintro/repository/PersonRepository.java @@ -3,6 +3,7 @@ package com.baeldung.springdatajdbcintro.repository; import com.baeldung.springdatajdbcintro.entity.Person; import org.springframework.data.jdbc.repository.query.Modifying; import org.springframework.data.jdbc.repository.query.Query; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/Application.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/Application.java new file mode 100644 index 0000000000..a08949585c --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/Application.java @@ -0,0 +1,15 @@ +package com.baeldung.springmultipledatasources; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.core.env.AbstractEnvironment; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "multipledatasources"); + SpringApplication.run(Application.class, args); + } + +} diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/Todo.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/Todo.java new file mode 100644 index 0000000000..56f513027b --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/Todo.java @@ -0,0 +1,48 @@ +package com.baeldung.springmultipledatasources.todos; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Todo { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String title; + private boolean completed; + + public Todo() { + } + + public Todo(String title) { + this.title = title; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public boolean isCompleted() { + return completed; + } + + public void setCompleted(boolean completed) { + this.completed = completed; + } + +} diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoDatasourceConfiguration.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoDatasourceConfiguration.java new file mode 100644 index 0000000000..b6a16eb7e4 --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoDatasourceConfiguration.java @@ -0,0 +1,28 @@ +package com.baeldung.springmultipledatasources.todos; + +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import javax.sql.DataSource; + +@Configuration +public class TodoDatasourceConfiguration { + + @Bean + @ConfigurationProperties("spring.datasource.todos") + public DataSourceProperties todosDataSourceProperties() { + return new DataSourceProperties(); + } + + @Bean + @Primary + public DataSource todosDataSource() { + return todosDataSourceProperties() + .initializeDataSourceBuilder() + .build(); + } + +} diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoJpaConfiguration.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoJpaConfiguration.java new file mode 100644 index 0000000000..e1c4e1c9be --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoJpaConfiguration.java @@ -0,0 +1,40 @@ +package com.baeldung.springmultipledatasources.todos; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Objects; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories( + basePackageClasses = Todo.class, + entityManagerFactoryRef = "todosEntityManagerFactory", + transactionManagerRef = "todosTransactionManager" +) +public class TodoJpaConfiguration { + + @Bean + public LocalContainerEntityManagerFactoryBean todosEntityManagerFactory( + @Qualifier("todosDataSource") DataSource dataSource, + EntityManagerFactoryBuilder builder) { + return builder + .dataSource(dataSource) + .packages(Todo.class) + .build(); + } + + @Bean + public PlatformTransactionManager todosTransactionManager( + @Qualifier("todosEntityManagerFactory") LocalContainerEntityManagerFactoryBean todosEntityManagerFactory) { + return new JpaTransactionManager(Objects.requireNonNull(todosEntityManagerFactory.getObject())); + } +} diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoRepository.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoRepository.java new file mode 100644 index 0000000000..ebdd59551b --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/todos/TodoRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.springmultipledatasources.todos; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TodoRepository extends JpaRepository { +} diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/Topic.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/Topic.java new file mode 100644 index 0000000000..390300ff1a --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/Topic.java @@ -0,0 +1,39 @@ +package com.baeldung.springmultipledatasources.topics; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Topic { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String title; + + public Topic() { + } + + public Topic(String title) { + this.title = title; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + +} diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/TopicDatasourceConfiguration.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/TopicDatasourceConfiguration.java new file mode 100644 index 0000000000..38daa13d7d --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/TopicDatasourceConfiguration.java @@ -0,0 +1,26 @@ +package com.baeldung.springmultipledatasources.topics; + +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; + +@Configuration +public class TopicDatasourceConfiguration { + + @Bean + @ConfigurationProperties("spring.datasource.topics") + public DataSourceProperties topicsDataSourceProperties() { + return new DataSourceProperties(); + } + + @Bean + public DataSource topicsDataSource() { + return topicsDataSourceProperties() + .initializeDataSourceBuilder() + .build(); + } + +} diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/TopicJpaConfiguration.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/TopicJpaConfiguration.java new file mode 100644 index 0000000000..a7daf54c07 --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/TopicJpaConfiguration.java @@ -0,0 +1,41 @@ +package com.baeldung.springmultipledatasources.topics; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Objects; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories( + basePackageClasses = Topic.class, + entityManagerFactoryRef = "topicsEntityManagerFactory", + transactionManagerRef = "topicsTransactionManager" +) +public class TopicJpaConfiguration { + + @Bean + public LocalContainerEntityManagerFactoryBean topicsEntityManagerFactory( + @Qualifier("topicsDataSource") DataSource dataSource, + EntityManagerFactoryBuilder builder + ) { + return builder + .dataSource(dataSource) + .packages(Topic.class) + .build(); + } + + @Bean + public PlatformTransactionManager topicsTransactionManager( + @Qualifier("topicsEntityManagerFactory") LocalContainerEntityManagerFactoryBean topicsEntityManagerFactory) { + return new JpaTransactionManager(Objects.requireNonNull(topicsEntityManagerFactory.getObject())); + } +} diff --git a/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/TopicRepository.java b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/TopicRepository.java new file mode 100644 index 0000000000..5aebc3fe87 --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/java/com/baeldung/springmultipledatasources/topics/TopicRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.springmultipledatasources.topics; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TopicRepository extends JpaRepository { +} diff --git a/persistence-modules/spring-data-jdbc/src/main/resources/application-jdbcintro.properties b/persistence-modules/spring-data-jdbc/src/main/resources/application-jdbcintro.properties new file mode 100644 index 0000000000..4980c71be4 --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/resources/application-jdbcintro.properties @@ -0,0 +1,6 @@ +#H2 DB +spring.jpa.hibernate.ddl-auto=none +spring.datasource.url=jdbc:h2:mem:persondb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=test diff --git a/persistence-modules/spring-data-jdbc/src/main/resources/application-multipledatasources.properties b/persistence-modules/spring-data-jdbc/src/main/resources/application-multipledatasources.properties new file mode 100644 index 0000000000..0f2b643498 --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/main/resources/application-multipledatasources.properties @@ -0,0 +1,9 @@ +spring.jpa.hibernate.ddl-auto=update +spring.datasource.todos.url=jdbc:h2:mem:todos +spring.datasource.todos.username=sa +spring.datasource.todos.password=null +spring.datasource.todos.driverClassName=org.h2.Driver +spring.datasource.topics.url=jdbc:h2:mem:topics +spring.datasource.topics.username=sa +spring.datasource.topics.password=null +spring.datasource.topics.driverClassName=org.h2.Driver diff --git a/persistence-modules/spring-data-jdbc/src/main/resources/application.properties b/persistence-modules/spring-data-jdbc/src/main/resources/application.properties index 45099222fc..2a0c259c00 100644 --- a/persistence-modules/spring-data-jdbc/src/main/resources/application.properties +++ b/persistence-modules/spring-data-jdbc/src/main/resources/application.properties @@ -1,8 +1,3 @@ #H2 DB -spring.jpa.hibernate.ddl-auto=none spring.h2.console.enabled=true -spring.datasource.url=jdbc:h2:mem:persondb -spring.datasource.driverClassName=org.h2.Driver -spring.datasource.username=sa -spring.datasource.password=test -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect \ No newline at end of file +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect diff --git a/persistence-modules/spring-data-jdbc/src/test/java/com/baeldung/springmultipledatasources/MultipleDatasourcesIntegrationTest.java b/persistence-modules/spring-data-jdbc/src/test/java/com/baeldung/springmultipledatasources/MultipleDatasourcesIntegrationTest.java new file mode 100644 index 0000000000..4d401396a2 --- /dev/null +++ b/persistence-modules/spring-data-jdbc/src/test/java/com/baeldung/springmultipledatasources/MultipleDatasourcesIntegrationTest.java @@ -0,0 +1,41 @@ +package com.baeldung.springmultipledatasources; + +import com.baeldung.springmultipledatasources.todos.Todo; +import com.baeldung.springmultipledatasources.todos.TodoRepository; +import com.baeldung.springmultipledatasources.topics.Topic; +import com.baeldung.springmultipledatasources.topics.TopicRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ActiveProfiles; + +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@ActiveProfiles("multipledatasources") +@DataJpaTest // no test database! +class MultipleDatasourcesIntegrationTest { + + @Autowired + TodoRepository todoRepo; + @Autowired + TopicRepository topicRepo; + + @Test + void shouldSaveTodoToTodoDB() { + Todo todo = new Todo("test"); + Todo saved =todoRepo.save(todo); + Optional result= todoRepo.findById(saved.getId()); + assertThat(result).isPresent(); + } + + @Test + void shouldSaveTopicToTopicDB() { + Topic todo = new Topic("test"); + Topic saved =topicRepo.save(todo); + Optional result= topicRepo.findById(saved.getId()); + assertThat(result).isPresent(); + } + +}