본문 바로가기
Back-End/Spring

멀티 모듈에서 JPA DDL 로그가 안나온다.

by 어렵다어려웡 2022. 6. 22.

 

멀티모듈이라는 단어가 나온지는 꽤 됐으나 최근에 멀티모듈이라는 것에 대해 들었다.

대략적으로 이해한 부분은 아래와 같다.

  1. 하나의 프로젝트가 방대해질수록 프로젝트가 가지는 의존성이 어마어마해진다.
  2. 프로젝트의 의존성들을 각 모듈에 따라 분리시킴으로써 모듈들이 자신의 역할을 수행하게하고 필요한 의존성들을 가지고 있게 한다.
  3. 새로운 구조가 생길 때마다 필요한 모듈을 미리 구현한 각각의 모듈을 사용함으로써 굳이 선언해서 사용하지 않음으로써 의존성을 분리시키고 관리를 좀 더 수월하게 하기 위함이다.

멀티 모듈로 프로젝트를 만들어가다보니 부딪히는 부분이 많았다.

 

첫 번째는 타 모듈에서 서버를 실행할 경우 Entity 를 가지고 있는 모듈의 의존성을 받아써도 JPA 관련 DDL 로그가 나타나지 않았다.

 

 

현재 만들고 있는 멀티 모듈의 초기 프로젝트 구조로 다음과 같다.

  • java-api : Web 과 관련된 REST API 를 제공하고 비즈니스 로직들을 담당하게 한다.
  • java-core : 데이터 접근 계층과 그에 관련된 역할을 담당한다.

java-api 모듈의 경우 비즈니스 계층으로 해두고 java-web 이라는 모듈을 따로 생성해서 프레젠테이션 계층으로 설정할까 고민중이지만, 우선은 처음하는 거기도 하고 같이 쓰게 했다.

 

그리고 각 모듈의 build.gradle 설정은 다음과 같이 했다.

// java-core
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    runtimeOnly 'com.h2database:h2'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

// java-api
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
// root
project(":java-api") {
    dependencies {
        implementation project(":java-core")
    }
}

다음으로 java-core 에서 패키지를 만들어서 EntityJpaRepository 를 추가했다.

@Entity
@Table(name = "board", indexes = {@Index(columnList = "title", name = "idx_title")})
public class Board {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "title", length = 50)
    private String title;

}

public interface BoardRepository extends JpaRepository<Board, Long> {
}

여기서 java-coreapplication.properties 파일에 다음을 추가했다.

당연히 core 모듈에서 JPAh2 의존성을 쓰고 있으니 해당 모듈에 추가하는 게 맞다고 생각했다.

spring.datasource.hikari.jdbc-url=jdbc:h2:mem://localhost/~/testdb;
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true

이후 java-api 모듈에서 서버를 실행했다.

 

 

기본적으로 JPA 를 사용하면 자동으로 테이블 정의어 로그가 나타나야 하는데 안나타났다.

생각해보니 java-api 모듈에는 Entity 관련 코드들이 없으며, api 모듈에 있는 Component 를 스캔하기 때문에 java-core 모듈에 작성된 Entity 들이 등록이 되지 않은 것이다.

그래서 검색을 해보았는데, @EntityScan 을 사용해서 다른 모듈을 읽어서 Entity 들을 스캔할 수 있었다.

 

따라서 코드를 추가.

@EntityScan("com.multi.core")
@SpringBootApplication
public class MultiModuleJavaApiApplication {

    public static void main(String[] args) {
        SpringApplication.run(MultiModuleJavaApiApplication.class, args);
    }

}

물론 여기서도 안됐다. 여전히 DDL 은 나오지 않았다.

 

여기서 application.properties 의 설정 코드를 직접 java-api 모듈에 옮겨서 동작을 시켰다.

 

드디어 해결을 했다.

어떻게 보면 당연한 결과이다. 이유는 다음과 같다.

  1. 서버를 실행하는 java-api 모듈은 환경설정이 비워져 있었다.
  2. JPAH2 관련 설정이 아무것도 없고 java-core 에 환경설정을 했으니 java-api 모듈을 실행해도 변화가 없었던 것이다.

여기서 추가적으로 생각해볼 부분이 있다.

JPAH2 설정은 java-core 모듈이 의존하는 덕분에 사용할 수 있는 부분이다. java-api java-core 의 모듈에 의존한다면 application.properties 에 작성한 환경설정 코드는 java-core 모듈에 선언하는 게 맞다고 생각했다.

 

그렇다고 생각했기 때문에, 만약 다른 모듈의 환경설정을 적용시킬 수 있다면 java-core 에 작성해서 쓰는게 맞는 것 같다라는 내 주관적인 결론을 내렸음.

 

검색을 해보니 금방 나왔는데, 기존에 단일 프로젝트에서 쓸 떄 쓰던 방법을 쓰면 됐다.

  1. @PropertySource 를 통한 방식 ( java-core 모듈 환경설정 이름을 변경했음 )
@EntityScan("com.multi.core") 
@SpringBootApplication 
@PropertySource({"classpath:application-core.properties"})

    2. properties 파일에 spring.config.import 선언하는 방식 ( 둘 중 하나를 사용 )

 spring.config.import=application-core.properties 
 spring.config.import=classpath:application-core.properties

https://stackoverflow.com/questions/58091902/how-to-inherit-application-properties-with-spring-boot-multiple-modules

 

How to inherit application.properties with spring boot multiple modules

I using spring boot multiple modules and i want inherit application.properties from parent . I have parent module : spring-ecommere-demo and sub module : model , core and security. In parent modul...

stackoverflow.com

 

 

 

한편으로는 java-api java-core 모듈에 의존하고 있기 떄문에 사실은 java-api 의 환경설정에 설정코드를 추가해서 사용해도 이미 의존하고 있는 부분이므로 상관없을 것 같다는 의견도 들었다.

 

서로 멀티 모듈에 대해서 잘 모르기 때문에 실무에서 얘기를 해볼 경우에는 각자 생각이 분명이 다를것 같기 떄문에 프로젝트 구조나 상황에 따라서 적용하는 위치가 달라질 것으로 예상한다.