본문 바로가기
spring & boot/JPA

[JPA] Java로 JPA 설정시 주의할점(.yml 설정 무시)

by lucas_owner 2024. 8. 12.

 

프로젝트 설정중, application.yml 파일의 JPA 설정이 무시되는 상황이 발생했다.

application.yml

 

@Entity 기준으로 Table 을 생성하게 해주는 옵션인 ddl-auto 를 Create 로 변경 후 Server 를 실행 시켰는데

Create table 쿼리 출력 X, DB에 table 생성 X 상황이 발생한것. 

 

프로젝트에 Multiple Datasource 설정과, 다른 몇몇 설정들을 추가하기전엔 잘 동작하고 있었던 설정이었다.

 

프로젝트 구조는 대략적으로 아래와 같다.

1. Multi module 환경
    - core (Entity, service, Repository)
    - api (Controller)
api 모듈은 core 모듈을 의존하고, scan 하여 사용중. 문제없었음.

2. Multiple Datasource 연결 구성중(maria{JPA}, oracle{MyBatis})

Stack Overflow 에서 비슷한 상황이 있었는지 찾아봤지만, 원하는 답변은 나오지 않았다. 

대부분 Main Class 의 @EntityScan 과 같은 어노테이션을 사용하여 Entity 스캔 설정이나, @PropertySource 사용과 같은 내용이었기 때문.

API Main Class

 

근데, Scan 은 이미 되고 있었고, 또한 CRUD 또한 정상적으로 동작을 하고 있었기 때문에, Spring 이 Entity 를 Scan 을 못하는것은 아니라고 생각이 되었고, 다른 원인을 찾던도중 생각이 났다. 

 

 

Spring이나, JPA 의 경우 사용자 즉 개발자가 별도의 설정을 하지 않을 경우, 혹은 최소한의 설정으로 간단하게 

프레임워크에서 제공하는 기본 설정을 통해 실행이 된다는것이였다. 


Spring Opinionated Defaults

Spring 의 원칙중 하나인  Opinionated Defaults는, 프레임워크가 기본적으로 설정이나 구조를 제공하는것을 의미하며

개발자가 명시적으로 설정하지 않는 한 프레임워크에서 기본적인 설정을 제공하는것이다. 

 

JPA 를 가장 빠르고 쉽게 사용하는 방법이었던 .yml 작성은 JPA 를 사용하기 위한 필수적인 설정과, 옵션들이었고

나는 Multiple Datasoruce 를 사용하기 위해 Java 로 별도의 JPA 설정을 지정 하였던게 원인이었던것이었다.

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.test.core.modules"},
        entityManagerFactoryRef = "mainEntityManagerFactory",
        transactionManagerRef = "mainTransactionManager"
)
public class DataSourceConfig {

    @Primary
    @Bean(name = "mainDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public DataSource mainDataSource() {
        return DataSourceBuilder.create()
                .type(HikariDataSource.class)
                .build();
    }


    @Primary
    @Bean(name = "mainEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean mainEntityManagerFactoryBean() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(mainDataSource());
        em.setPackagesToScan("com.test.core.modules");
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

        // Add JPA properties -
        Properties jpaProperties = new Properties();
        jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.MariaDBDialect");
        jpaProperties.put("hibernate.show_sql", "true");
        jpaProperties.put("hibernate.format_sql", "true");
        jpaProperties.put("hibernate.hbm2ddl.auto", "create");
        em.setJpaProperties(jpaProperties);

        return em;
    }

    @Primary
    @Bean(name = "mainTransactionManager")
    public JpaTransactionManager mainTransaction() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(mainEntityManagerFactoryBean().getObject());
        return transactionManager;
    }

}

위의 코드는 JPA 설정을 위한 Java Class 이고

 

해당 Class에서 설정한 내용때문에 application.yml 의 설정이 무시된것. 

정확하게 말하면  application.yml 설정을 위의 Class 가 오버라이드 한것이다. 

@Configuration 클래스를 통해 수동으로 정의한 Bean 이 application.yml 과 같은 설정을 대체한다. 

@Configuration 클래스 내부에 @Bean 으로 정의된 내용은 yml 설정 보다 우선시 된다.

 

-> 그러면 Stack overflow 의 답변대로 @PropertySource 를 추가해서 .yml 파일을 잡아주면 되지않나요? 

현재 내 프로젝트의 경우 Multi Module 로 분리 되어있고, DataSource 설정은 Core 모듈에 있기 때문에 파일을 찾지못하는 오류가 발생한다.

Config.class
File Not Found

그렇기에 불편하지만 Properties를 하나하나 추가해주는 방식으로 해당 문제를 수정 할 수 있었다. 

반응형

댓글