모르지 않다는 것은 아는것과 다르다.

Spring Jpa

JPA DB 수동설정

채마스 2022. 3. 24. 21:25

DB 를 수동으로 설정해야할 경우

  • DB를 하나만 사용하면 굳이 수동으로 설저할 필요가 없다. 하지만 아래와 같은 경우엔 DB를 수동으로 설정할 필요가 있다.
  • 자바 코드로 DataSource, TransactionManager 를 수동 세팅해야 하는 경우
  • configuration properties 로 커버되지 않는 세밀한 옵션을 줄 때
  • 다중 DataSource 를 사용할 때

 

DB 세팅 요소

  • 먼저 DataSource 를 세팅한다. -> DB 설정
  • 그 다음 DataSource 를 바탕으로 EntityManagerFactory 를 세팅한다. -> PA 엔티티 관리
  • 그 다음 EntityManagerFactory를 바탕으로 LocalContainerEntityManagerFactoryBean를 세팅한다. -> 트랜잭션 관리

 

설정 코드

@EnableJpaAuditing
public class JpaConfig {

    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.hyunwook.servicedesk");
        factory.setDataSource(dataSource());
        return factory;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory2() {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.hyunwook.servicedesk");
        factory.setDataSource(dataSource());
        return factory;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {

        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory);
        return txManager;
    }
    @Bean
    public PlatformTransactionManager transactionManager2(EntityManagerFactory entityManagerFactory2) {

        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory2);
        return txManager;
    }

    @Bean
    public ChainedTransactionManager chainedTransactionManager(
            PlatformTransactionManager transactionManager,
            PlatformTransactionManager transactionManager2
    ) {
        return new ChainedTransactionManager(transactionManager, transactionManager2);
    }

}
  • 위와 같이 DataSource 가 2개일 때, EntityManagerFactory 와 LocalContainerEntityManagerFactoryBean 를 따로 구성해준다.
  • LocalContainerEntityManagerFactoryBean 의 경우, 추가적인 예외 처리 기능 때문에, 인터페이스 말고 구현체를 직접 빈으로 등록한다.
  • 마지막으로, ChainedTransactionManager 를 통해서 여러 개의 트랜잭션 매니저를 묶는다.
    • 여기서 순서가 중요한데, 로직상 중요한 트랜잭션을 뒤에 위치시켜야 한다.
    • 또한, spring boot 2.5 버전부터 Deprecated 되었기 때문에, 대안으로 TransactionSyncronization 를 사용해서 구현해야 된다.




REFERENCES

  • 김은호님의 Spring Data JPA

'Spring Jpa' 카테고리의 다른 글

JPA에서 여러 종류의 영속성 관리하기  (0) 2023.08.28
JPA 관련 애노테이션 정리  (0) 2022.03.24
프록시와 연관관계 관리  (0) 2022.02.27
JPA Id 생성전략 설정하기  (0) 2022.02.27
영속성 컨텍스트  (0) 2022.02.27