1. DataSource 설정 방법
JPA로 여러 데이터베이스를 참조해야하는 경우, JPA에서 바라보는 데이터베이스를 설정해주는 값, 그에 맞는 트랜잭션 매니저, 엔티티 매니저 설정을 아래처럼 설정해줘야한다. 예를 들어 Abc, Def 도메인에 대해 설정하는 경우 아래처럼 설정한다.
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = "com.project.domain.abc",
entityManagerFactoryRef = "abcEntityManagerFactory",
transactionManagerRef = "abcTransactionManager"
)
public class AbcDataSourceConfig {
//DataSource 기본 정보를 바인딩
@Primary
@Bean
@ConfigurationProperties("spring.datasource")
public DataSourceProperties abcDataSourceProperties() {
return new DataSourceProperties();
}
//위 정보를 기반으로 실제 DataSource 객체 생성
@Primary
@Bean
public DataSource abcDataSource() {
return abcDataSourceProperties().initializeDataSourceBuilder().build();
}
////Jpa 설정 바인딩. ddl-auto 설정을 none으로 바꾸는등의 처리 가능
@Bean
@Primary
public JpaProperties JpaProperties() {
return new JpaProperties();
}
//JPA의 EntityManagerFactory 생성
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean abcEntityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(abcDataSource())
.packages("com.project.entity.abc")
.persistenceUnit("abc")
.build();
}
//JPA의 JpaTransactionManager 생성. 해당 엔티티 매니저가 관리하는 트랜잭션을 처리한다.
@Primary
@Bean
public PlatformTransactionManager abcTransactionManager(
@Qualifier("abcEntityManagerFactory") EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
}
나머지 Def 도메인에 대해서도 이름만 변경하여 생성해주면 된다.
2. 유의사항: JpaQueryFactory에서 스프링이 자동 관리해주도록 처리
Querydsl을 사용하기 위해 JpaQueryFactory를 설정해줘야하는데, 아래처럼 설정할 수도 있다.
@Primary
@Bean
public JPAQueryFactory abcQueryFactory(@Qualifier("abcEntityManagerFactory") EntityManagerFactory emf) {
return new JPAQueryFactory(emf.createEntityManager());
}
그런데 이렇게 사용하면, 내가 직접 EntityManager를 관리하는 JpaQueryFactory를 사용하겠다는 의미가 된다. 즉 스프링이 관리하는 트랜잭션과 무관한 인스턴스를 반환하여 실제 코드에서 해당 엔티티 매니저를 사용하여 @Transactional을 하더라도 JPAQueryFactory가 사용하는 EntityManager는 동일 트랜잭션 컨텍스트 밖의 DB 상태를 바라보게 된다.
그래서 Test 등에서 다른 컨텍스트를 바라보면서 이미 detached된 영속성 객체를 persist 할려고 한다는 아래와 유사한 에러를 맞게 된다.
detached entity passed to persist ...
이에 따라 아래처럼 @PersistenceContext를 활용하여 각 도메인의 EntityManager를 직접 주입해준다. @PersistenceContext는 JPA에서 EntityManager를 주입받기 위한 어노테이션이다.
@Configuration
public class QuerydslConfig {
@PersistenceContext(unitName = "abc")
private EntityManager abcEntityManager;
@PersistenceContext(unitName = "def")
private EntityManager defEntityManager;
@Primary
@Bean
@Qualifier("abcQueryFactory")
public JPAQueryFactory abcQueryFactory() {
return new JPAQueryFactory(abcEntityManager);
}
@Bean
@Qualifier("defQueryFactory")
public JPAQueryFactory defQueryFactory() {
return new JPAQueryFactory(defEntityManager);
}
}
정리하자면 MultidataSource로 JPA 및 Querydsl을 사용하기 위해서, 각각의 도메인별로
- DataSource, JPA Properties 설정을 한다.
- EntityManagerFactory(EntityManager도 함께), TransactionManager를 설정해준다.
- Querydsl을 사용하기 위한 JPAQueryFactory 빈 생성 시, @PersistenceContext를 통해 스프링이 직접 EntityManager를 주입하도록 한다.
'Programming-[Backend] > JPA' 카테고리의 다른 글
| [TIL] Soft Delete hibernate, @SQLRestriction (1) | 2025.07.23 |
|---|---|
| [TIL] 양방향 연관관계 복습 + Instancio + cascade (2) | 2025.06.02 |
| [TIL] JPA @ManyToMany 적용, 테이블 이름과 컬럼, 저장 처리 방식 (0) | 2023.05.19 |
| [링크] could not initialize proxy - no Session (0) | 2023.05.02 |
| [TIL] JPA Expressions Date 오늘 날짜 또는 상수 값 넣기 : dateTemplate, SQL function(내장함수) (0) | 2022.05.17 |