프로젝트 설정중, application.yml 파일의 JPA 설정이 무시되는 상황이 발생했다.
@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 사용과 같은 내용이었기 때문.
근데, 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 모듈에 있기 때문에 파일을 찾지못하는 오류가 발생한다.
그렇기에 불편하지만 Properties를 하나하나 추가해주는 방식으로 해당 문제를 수정 할 수 있었다.
'spring & boot > JPA' 카테고리의 다른 글
[JPA]JpaRepository 원리 및 내부 분석(EntityManager 자동주입, 상속관계) (0) | 2023.08.30 |
---|---|
[JPA] JPA N+1 문제와, 해결방법 정리 (0) | 2023.02.21 |
[JPA] 영속성 컨텍스트(Persistence Context), Entity Manager (0) | 2023.02.02 |
[JPA] JPA, ORM 이란 무엇인가? (0) | 2023.01.31 |
댓글