-
[JPA-Error] Table [DB명.Table명] doesn't exist 해결방법legacy/JPA 2024. 2. 21. 15:10
문제 발생
스프링부트에서 테이블을 생성하여 값을 저장하려고 하면 다음과 같은 오류가 발생했다.
org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement [Table 'cicd_db.users' doesn't exist] [insert into users (age,username) values (?,?)]; SQL [insert into users (age,username) values (?,?)]
문제 원인
"Table 'cicd_db.users' doesn't exist" 이부분이 핵심인 듯하다. 나는 "Users" 테이블에 데이터를 삽입하려고 하는데 실제로는 "cicd_db.users" 테이블에 삽입하려고 시도하고 있다.
나는 DB명으로 cicd_db를 사용했고, 데이터를 삽입하려고 하는 테이블명은 "users"였다. 보아하니 테이블명으로 insert 하는 것이 아닌 DB명.테이블명으로 insert 하려고 시도한다.
User.class
@Getter @Entity @Table(name = "USERS") @Builder @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") private Long id; private String username; private int age; }
application.yml
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: ${SPRING_DATASOURCE_URL} username: ${SPRING_DATASOURCE_USERNAME} password: ${SPRING_DATASOURCE_PASSWORD} # JPA 설정 jpa: database: mysql database-platform: org.hibernate.dialect.MySQLDialect hibernate: ddl-auto: none properties: hibernate: dialect: org.hibernate.dialect.MySQLDialect format_sql: true # 쿼리 로그 포맷 (정렬) show_sql: true # 쿼리 로그 출력
Test.class
@SpringBootTest @Transactional class UserServiceTest { @Autowired UserService userService; @Test @DisplayName("사용자 등록") void saveUser() { User user = User.builder() .username("이희망") .age(99) .build(); User savedUser = userService.save(user); assertThat(savedUser).isEqualTo(user); assertThat(savedUser.getUsername()).isEqualTo("이희망"); assertThat(savedUser.getAge()).isEqualTo(99); } }
application.yml 파일을 보면 "ddl-auto: none"을 사용하고 있다. hibernate는 "ddl-auto: none"을 사용하면 어떤 DDL 작업도 수행하지 않는다. 따라서 Entity 클래스에 정의된 테이블이나 스키마가 실제 데이터베이스에 존재해야 한다. 즉, 테이블이나 스키마를 자동으로 생성하거나 업데이트하지 않는다. 따라서 문제가 발생한 것이다.
문제 해결
"ddl-auto: none" -> "ddl-auto: create"로 변경한다. "ddl-auto: create"의 경우 hibernate가 Entity 클래스를 기반으로 데이터베이스 스키마를 생성하게 되어 문제가 해결된다.
여기서 주의할 점은 실제 운영환경에서는 "ddl-auto: create"를 사용해서는 안 된다. 왜냐하면 운영 환경에서는 스키마를 자동으로 생성하거나 변경해서는 안 되기 때문이다. 실제 운영환경에서는 "ddl-auto: validate" 또는 비워두는 것이 좋다.