주요 설정 내용
리소스 경로 설정
DB 정보 설정(Datasource)
Hibernate 설정
ddl-auto
dialect
설정된 다중 DB는 Repository package 명으로 구분
초기 설정이 복잡한 편이나, 천천히 살펴보면 크게 어렵지 않음
이 글에서는 1개의 Entity로 2개의 Database에 값을 넣는 예제로 진행합니다.
package com.jpa.master.entity;
@Entity
@Table(schema = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@Column(unique = true, nullable = false)
private String email;
private int age;
}
package com.jpa.master.repository;
@Repository
public interface UserMasterRepository extends JpaRepository<User, Integer> {}
package com.jpa.second.repository;
@Repository
public interface UserSecondRepository extends JpaRepository<User, Integer> {}
#### Master DataSource Configuration1
spring.datasource.username=[user]
spring.datasource.password=[Password]
spring.datasource.jdbcUrl=[URL]
#### Second DataSource Configuration2
spring.second-datasource.username=[user]
spring.second-datasource.password=[Password]
spring.second-datasource.jdbcUrl=[URL]
Master DB용 java 설정파일 생성
설정 파일은 다음과 같이 구성되어 있음
DataSource 설정
EntityManagerFactory 설정
TransactionManager 설정
다중 DB를 설정할 때는, @Primary 어노테이션을 이용하여 Master가되는 Datasouce를 지정해야합니다.
@Configuration
@PropertySource({ "classpath:application.properties" })
@EnableJpaRepositories(
basePackages = "com.jpa.master.repository", // Master Repository 경로
entityManagerFactoryRef = "masterEntityManager",
transactionManagerRef = "masterTransactionManager"
)
public class MainDatabaseConfig {
@Autowired
private Environment env;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean masterEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(masterDataSource());
//Entity 패키지 경로
em.setPackagesToScan(new String[] { "com.jpa.master.entity" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
//Hibernate 설정
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
@Primary
@Bean
@ConfigurationProperties(prefix="spring.datasource")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean
public PlatformTransactionManager masterTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(masterEntityManager().getObject());
return transactionManager;
}
}
두번째 DB용 java 설정파일 생성 (설정 파일 구성은 메인과 동일함)
소스코드 복붙하다가 하는 실수
@Primary 어노테이션은 꼭 지워야 함
@Configuration
@PropertySource({ "classpath:application.properties" })
@EnableJpaRepositories(
basePackages = "com.jpa.second.repository", // Second Repository 경로
entityManagerFactoryRef = "secondEntityManager",
transactionManagerRef = "secondTransactionManager"
)
public class SecondConfig {
@Autowired
private Environment env;
@Bean
public LocalContainerEntityManagerFactoryBean secondEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(secondDataSource());
em.setPackagesToScan(new String[] { "com.jpa.master.entity" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
@Bean
@ConfigurationProperties(prefix="spring.second-datasource")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public PlatformTransactionManager secondTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(secondEntityManager().getObject());
return transactionManager;
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@AutoConfigureTestDatabase(replace = Replace.NONE)
@SpringBootTest
public class JPAMultipleDBTest {
@Autowired
UserMasterRepository masterRepo;
@Autowired
UserSecondRepository secondRepo;
@Test
public void insertTest() {
User user = new User();
user.setAge(28);
user.setEmail("test@spring.com");
user.setName("name");
secondRepo.save(user);
masterRepo.save(user);
}
}