![[SpringBoot] org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table if exists user cascade " via JDBC [Syntax error in SQL statement "drop table if exists [*]user cascade "; expected "identifier";]](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwZkbZ%2FbtsnqTRpdOP%2FT2OSVy0PXcefoku7o8jOK0%2Fimg.png)
에러 메세지
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table if exists user cascade " via JDBC [Syntax error in SQL statement "drop table if exists [*]user cascade "; expected "identifier";]
원인
테스트 코드 공부를 마치고, 적용을 위해 토이 프로젝트를 진행하다 처음 마주친 에러이다. 에러 상황은 회원가입 시 User Entity에서 Repository를 통해 save할 때 발생하였으며 RED 상황이 아닌 hibernate에서 정말 에러를 뱉어내고 있었다.
테스트 로직은 아래처럼, RED 상황을 테스트하기 위한 코드를 작성했다.
@SpringBootTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@DisplayName("회원가입 시 ID가 중복되면 회원가입이 불가능하다.")
@Test
void signUpWhenIDIsDuplicated(){
//given
LocalDateTime createDateTime = LocalDateTime.now();
User currentUser = createUser("diehreo", "단타왕", "1234567890", "01010101010", USER, createDateTime);
User newUser = createUser("diehreo", "떡락가즈아", "123456789012345", "01010101010", USER, createDateTime);
//when
userRepository.save(currentUser);
//then
assertThrows(DataIntegrityViolationException.class, () -> userRepository.save(newUser));
}
private static User createUser(String userId, String nickName, String passWd, String phoneNum, UserType userType, LocalDateTime createDateTime) {
return User.builder()
.userId(userId)
.nickName(nickName)
.passWd(passWd)
.phoneNum(phoneNum)
.userType(userType)
.createDateTime(createDateTime)
.build();
}
}
CommandAcceptanceException은 명령을 수행하지 못했을 때 발생하는 에러이다. 그럼 DB를 통해 어떤 명령을 수행하지 못했기에 에러가 발생했을까? 에러 코드에 답이 있다.
drop table if exists user cascade " via JDBC [Syntax error in SQL statement
"drop table if exists [*]user cascade "; expected "identifier";]
에러 코드에서처럼 drop table if exists [*] user cascade에서 식별자가 필요하다는 에러를 뱉어냈다.
User라는 테이블을 삭제하라는 쿼리문에서, user가 예약어이기 때문에 조치가 필요했다.
해결
@Table 애너테이션을 붙여 매핑 테이블 이름을 변경해주거나 설정 파일에서 설정을 통해 예약어가 아님을 명시해준다.
spring:
datasource:
url: jdbc:h2:mem:testdb;NON_KEYWORDS=USER
나는 두 가지 방법 말고, 그냥 User 엔티티 명을 Member로 변경해주었다. 차후 DB Table명도 Member로 변경할 계획이다.
잘 동작하는 것을 확인할 수 있다.
공부 - Hibernate 동작 과정
현재 내 로직에서 어떻게 Hibernate가 동작하길래 처음부터 막히는지 알아봤다.
1. 테스트 실행
2. Hibernate에서 drop table 실행하여 해당 Entity가 존재한다면 삭제, 없으면 무시
3. save()를 통한 저장 수행
4. 수행 시 Unique에 걸려 DataIntegrityViolationException 발생
5. RED Test 성공.
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!