spring boot 실행 시 data.sql로 데이터 세팅하기 schema.sql, data.sql 파일을 resource 디렉토리의 루트 경로에 작성하면 ScriptUtils에 의해 sql script를 실행하게된다. 기본 이름은 schema, data이지만 @Sql을 사용하면 다른 이름의 .sql 파일을 지정해줄 수 있다. 위 과정이 스프링 부트 2.4 버전까지는 하이버네이트의 ddl-auto 설정대로 테이블을 생성하게 된 후 실행되었다. 하지만 2.5 버전부터 스크립트가 먼저 실행된 후 JPA ddl-auto가 실행된다. 그렇기 때문에 ddl-auto가 create로 되어있어 data.sql로 insert한 데이터가 다 지워지게 될 수 있다. 이런 경우 defer-datasource-initial..
문제 Controller에 대한 Test를 진행하기 위해 @WebMvcTest를 진행했다. @SpringBootTest는 모든 구성 요소를 로드해서 실제 실행과 같은 환경에서 테스트를 진행하기 때문에 매우 무겁다는 단점이 있어 Controller에 대한 테스트는 @WebMvcTest를 사용하는 것으로 알고있어서 선택한 것이었다. 하지만 @WebMvcTest가 어떻게 동작하는지에 대해 모르는 상태였고, 그에 따라 "jpa metamodel must not be empty!" 라는 에러 메세지를 만나게 되었고, 문제를 해결하면서 @WebMvcTest에 대해 공부해보았다. 원인 jpa metamodel must not be empty는 Auditing 관련 빈을 생성하지 않고 @EnableJpaAuditing..
문제 상황 H2 데이터베이스에 연결한 상태로 JPA에 대한 테스트 코드를 작성하는 도중 테이블이 정상적으로 생성되었음에도 아래와 같은 "테이블을 찾을 수 없다"는 에러 메세지를 보게되었고, 해당 문제를 해결하기 위해 @DataJpaTest에 대해 찾아보았다. could not prepare statement [Table "ARTICLE" not found (this database is empty); SQL statement: @DataJpaTest @DataJpaTest는 JPA에 대한 테스트 실행 시 테스트를 위한 내장 데이터베이스를 생성해서 실제 DB에 영향을 주지않고 테스트 할 수 있도록 환경을 제공해준다. @DataJpaTest의 동작 과정은 EntityScan을 통해 Entity들을 읽어 스키..
JPA Auditing이란? 생성자, 수정자, 생성 시간, 수정 시간과 같은 메타 데이터를 자동으로 관리할 수 있는 JPA 라이브러리이다. Auditing 적용방법 @EnableJpaAuditing JPA Auditing 기능을 활성화하는 애노테이션으로 꼭 활성화를 시켜주어야 Auditing이 정상적으로 동작한다. * Config class에서 @EnableJpaAuditing을 넣어주어도 무방하다. @EnableJpaAuditing @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @EntityLis..
테스트 코드를 작성했을 때의 장점 중에 더 좋은 설계, 더 낮은 결합도를 가진 코드를 만들 수 있다는 내용이 있었다. 더 낮은 결합도는 보통 내부에서 생성자를 통해 생성하는 것이 아닌 외부로부터 값을 주입 받는 식의 DI를 통해 해결할 수 있다. 그 과정을 실제 코드를 통해 기록을 남겨놓으면 더 이해가 쉬울 것 같아 적어본다. 테스트 상황 0~12 사이의 랜덤한 길이를 가진 패스워드를 생성하는 코드를 테스트 하고싶다. 잘못된 테스트 코드 작성 예시 @DisplayName("패스워드를 초기화한다.") @Test void passwordTest(){ //given User user = new User(); //when user.initPassword(); //then assertThat(user.getPas..
Generic이란? 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법이다. 예시1 class Person { public T info; } Person p1 = new Person(); Person p2 = new Person(); Person의 Info를 String으로 받을 수도 있고, StringBuilder로 받을 수도 있다. 따라서 p1의 타입은 Person 클래스 타입이고 내부에서 사용하는 제네릭 변수의 타입이 String이라는 뜻이다. Generic이 필요한 이유 class StudentInfo{ public int grade; StudentInfo(int grade){ this.grade = grade; } } class StudentPerson{ public StudentInf..