BAEL-5323: Merge sources into existing persistence module (#11804)

* BAEL-5323: Spring Boot with multiple data sources

* BAEL-5323: small fixes

* BAEL-5323: fix test class

* BAEL-5323: Refactor configuration classes

* BAEL-5323: Set proeprty to private

* BAEL-5323: rename test class to follow naming conventions

* BAEL-5323: merge sources into existing persistence module

* BAEL-5323: merge sources into existing persistence module
This commit is contained in:
Ralf Ueberfuhr 2022-02-11 20:49:43 +01:00 committed by GitHub
parent a8a362dfcb
commit 7f84edf0f8
19 changed files with 324 additions and 13 deletions

BIN
.local-db/todos.mv.db Normal file

Binary file not shown.

BIN
.local-db/topics.mv.db Normal file

Binary file not shown.

View File

@ -21,11 +21,19 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
</project>

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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()));
}
}

View File

@ -0,0 +1,6 @@
package com.baeldung.springmultipledatasources.todos;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TodoRepository extends JpaRepository<Todo, Long> {
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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()));
}
}

View File

@ -0,0 +1,6 @@
package com.baeldung.springmultipledatasources.topics;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TopicRepository extends JpaRepository<Topic, Long> {
}

View File

@ -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

View File

@ -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

View File

@ -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
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

View File

@ -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<Todo> result= todoRepo.findById(saved.getId());
assertThat(result).isPresent();
}
@Test
void shouldSaveTopicToTopicDB() {
Topic todo = new Topic("test");
Topic saved =topicRepo.save(todo);
Optional<Topic> result= topicRepo.findById(saved.getId());
assertThat(result).isPresent();
}
}