ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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" 또는 비워두는 것이 좋다.

Designed by Tistory.