2024. 5. 3. 19:39ㆍ스프링 (Spring)/스프링 데이터 (Spring Data)
HSQL?
Spring 문서의 Data 항목을 보면 간단하게 만들 수 있는 Embeded DataSource를 소개해줍니다.
그냥 쉽게 말해 외부 데이터베이스 연결 없이 자체 구축되는 데이터베이스라고 이해하고 있습니다.
후보군은 H2, HSQL, Derby 이렇게 있는데, 저는 HSQL로 선택했습니다.
Configure HSQLDB for Test
시작 전에 application.yml 파일을 기존 프로파일과 구분되도록 test 디렉터리에 별도로 만들어줍니다.
가이드를 읽으면 바로 마주치는 글이 있었는데
딱히 필요는 없다만, 있어도 성능에는 크게 문제가 되지 않으니 그냥 함께 반영해봅니다.
// application-test.yml
spring:
config:
name: App
datasource:
generate-unique-name: true
...
그리고 build.gradle.kts 에서 다음 한 줄을 추가해줍니다.
(spring-boot-starter-data-jpa은 이미 있다고 가정합니다)
dependencies {
...
runtimeOnly(testImplementation(group = "org.hsqldb", name = "hsqldb"))
}
끝났습니다.
이제 테스트 코드로 돌아와서,
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ActiveProfiles
@ActiveProfiles("test")
@SpringBootTest
class ApplicationTest {
@Test
fun contextLoads() {
}
}
실행해주면...!
잘 되네요.
Situation
이걸 마지막에 위치했던 이유는, 그냥 푸념이라서 영양가가 없기 때문입니다.
발단은 API 문서 생성을 위한 Restdocs 적용이었네요. 적용기는 다음 글에서 다루는 걸로 하고... (공식 문서 미리보기)
실행할 테스트는 아래처럼 생겼습니다.
@SpringBootTest
class TestingRestdocsApplicationTests {
@Test
@Throws(Exception::class)
fun contextLoads() {
}
}
테스트는 실제 데이터베이스와 연결하지 않고 mock을 사용하므로 (참고 : Mockito를 이용해 JpaRepository 테스트하기)
실제로 제 프로젝트에서는 다음과 같이 생겼더라죠.
@SpringBootTest(classes = [TestDataSourceConfiguration::class])
class TestingRestdocsApplicationTests {
@Test
fun contextLoads() {
}
}
아이디어는 Spring에서 Gmail 보내기에서 나왔습니다.
그러나 믿고 싶지 않았던 사실은...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786)
...
caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:276)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:52)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:136)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:247)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
at io.hypersistence.utils.hibernate.type.HibernateTypesContributor.contribute(HibernateTypesContributor.java:78)
at org.hibernate.boot.internal.MetadataBuilderImpl.applyTypes(MetadataBuilderImpl.java:295)
이제 피할 수 없다고 생각, test 전용 profile을 만들기로 합니다.
spring:
config:
name: App
mail:
properties:
"[mail.smtp.connectiontimeout]": 5000
"[mail.smtp.timeout]": 3000
"[mail.smtp.writetimeout]": 5000
logging:
level:
root: INFO
server:
error:
include-message: always
이제 돌아와 ActiveProfile을 추가해줍니다.
@ActiveProfiles("test")
@SpringBootTest(classes = [TestDataSourceConfiguration::class])
class TestingRestdocsApplicationTests {
@Test
fun contextLoads() {
}
}
그리고 TestDataSourceConfiguration에서 광기의 Mocking 작업을 했으나...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionRepository' defined in ...SessionRepository defined in @EnableJpaRepositories declared on DolphinDataSourceConfiguration: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Metamodel must not be null
...
Caused by: java.lang.IllegalArgumentException: Metamodel must not be null
수습하지 못할 지경까지 와버렸네요.
저 Repository 빈들을 등록할 마음은 없습니다.
또 아무리 리서치를 하고 설정을 바꿔도 결국 의미는 없었고요. (무의미한 내 시간...)
그래서 그냥 인메모리 데이터베이스를 적용하기로 마음 먹습니다.
'스프링 (Spring) > 스프링 데이터 (Spring Data)' 카테고리의 다른 글
JPA(Jakarta Persistence API) - Type Conversion (0) | 2024.08.02 |
---|---|
JPA(Jakarta Persistence API) - Entity Listener (0) | 2024.07.31 |
JPA(Jakarta Persistence API) - Entity Operation (1) | 2024.06.06 |
JPA(Jakarta Persistence API) - Entity (0) | 2024.05.22 |
JPA(Jakarta Persistence API) - Overview (0) | 2024.05.19 |