01. 문제 상황
패스트캠퍼스 강의를 들으며 실습을 진행하던 도중, 에러를 마주했다.
간단한 유저 엔티티를 작성하고 이를 저장하는 실습이였다.
1. domain 패키지에 User 클래스를 작성하였다. (다만 @Table(name="Users")로 테이블 명을 따로 지정해주었다. User가 키워드이기 때문에!!!)
package com.fastcampus.jpa.bookmanager.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.*;
import java.time.LocalDateTime;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@Entity
@Table(name = "Users")
public class User {
@Id @GeneratedValue
private Long id;
private String name;
private String email;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
2. repository 패키지에 UserRepository를 작성하였다.
package com.fastcampus.jpa.bookmanager.repository;
import com.fastcampus.jpa.bookmanager.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
3. application.yml에 다음과 같이 작성하였다.
spring:
h2:
console:
enabled: true
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
4. test 폴더에 resources 폴더를 만들어 data.sql 을 다음과 같이 작성했다. 이렇게 하면 테스트 시 이 파일을 먼저 실행한다고 한다.
call next value for hibernate_sequence;
insert into Users('id', 'name', 'email', 'created_at', 'updated_at') values ('1', 'kms1', 'kms1@naver.com', now(), now());
call next value for hibernate_sequence;
insert into Users('id', 'name', 'email', 'created_at', 'updated_at') values ('2', 'kms2', 'kms2@naver.com', now(), now());
call next value for hibernate_sequence;
insert into Users('id', 'name', 'email', 'created_at', 'updated_at') values ('3', 'kms3', 'kms3@naver.com', now(), now());
call next value for hibernate_sequence;
insert into Users('id', 'name', 'email', 'created_at', 'updated_at') values ('4', 'kms4', 'kms4@naver.com', now(), now());
call next value for hibernate_sequence;
insert into Users('id', 'name', 'email', 'created_at', 'updated_at') values ('5', 'kms5', 'kms5@naver.com', now(), now());
5. repository가 잘 동작하는지 테스트를 하기 위해 test 폴더 하위의 repository 폴더에 UserRepositoryTest 클래스를 만들고 다음과 같이 작성했다.
package com.fastcampus.jpa.bookmanager.repository;
import com.fastcampus.jpa.bookmanager.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void crud() { // create, read, update, delete
userRepository.save(new User());
userRepository.findAll().forEach(System.out::println);
}
}
테스트를 위해 실행 버튼을 눌렀더니 다음과 같은 오류가 발생했다.
Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Failed to execute SQL script statement #1 of file [/Users/kangminseo/Documents/GitHub_Project/jpa/bookmanager/build/resources/test/data.sql]: call next value for hibernate_sequence
02. 원인
SQL에 문제가 있다고 한다! id 값을 지정해주면 안되는건가? (근데 강의에서는 작성했는데 뭐가 바뀌었나?) 부터, 테스트 하면 연결된 H2 데이터베이스가 변경(?) 되는건가? 30분 정도 삽질을 했다. 구글링도 많이 해봤는데, 해결 방법은 의외로 간단했다.
03. 오류 해결
1. application.yml 에 defer-datasource-initialization: true 를 추가했다. 아래는 전체 application.yml 파일이다.
spring:
h2:
console:
enabled: true
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
defer-datasource-initialization: true
2. test 폴더 하위의 resources 폴더의 data.sql을 data_sql.sql로 바꾼다. (왜 이렇게 해야하는지 모르겠지만 그렇다고 함.. 자료를 더 찾아봐야겠다.)
참고한 글 : https://jjunii486.tistory.com/332
이 분 아니였다면 강의 듣는 걸 포기했을지도.....