인프런 커뮤니티 질문&답변

awdsza님의 프로필 이미지

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

JPA와 DB 설정, 동작확인

DDL 변경후 테스트 질문입니다.

해결된 질문

23.08.03 08:45 작성

·

444

1

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
여기에 질문 내용을 남겨주세요.

안녕하세요 DB Connection 설정 테스트 하고나서 해당 영상을 보고 테스트 코드 까지 작성하고나서 Entity와 Repository DDL을 변경하고나서 이전 테이블의 칼럼내용으로 조회가 되서 질문 드립니다.

  • Entity자바 코드 입니다

    @Entity
    @Getter
    @Setter
    public class Bubjeongdong {
        @Id
        private String bubjeongdongCode;
    
        private int bubjeongdongLevel;
    
        private String bubjeongdongName;
    
        private String isClose;
    }
  • Repository 코드입니다.

    public Bubjeongdong find(String bubjeongdongCode){
        return em.find(Bubjeongdong.class,bubjeongdongCode);
    } 
  • 테스트 코드입니다

    Bubjeongdong bubjeongdong = bubjeongdongRepository.find("1156011000");
    
    org.assertj.core.api.Assertions.assertThat(bubjeongdong.getBubjeongdongCode()).isEqualTo("1156011000");
  • DDL 전문입니다.

    CREATE TABLE bubjeongdong (

    bubjeongdong_level int NOT NULL,

    bubjeongdong_code varchar(255) NOT NULL,

    bubjeongdong_name varchar(255) DEFAULT NULL,

    is_close varchar(255) DEFAULT NULL,

    PRIMARY KEY (`bubjeongdong_code`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

  • application.yml 파일 내용입니다.

    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/estate?serverTimezone=UTC&characterEncoding=UTF-8
        username: estate
        password: 
        driver-class-name: com.mysql.cj.jdbc.Driver
    
      jpa:
        hibernate:
          ddl-auto: none
        properties:
          hibernate:
            # 해당 설정은 System.out.println을 통해찍는거(권장하지않음)
    #        show_sql: true
    
            format_sql: true
    
    logging:
      level:
        # 로거를 통해찍음.
        org.hibernate.SQL: debug
    • 로그에 조회된 쿼리입니다.

      select

      b1_0.bubjeongdong_code,

      b1_0.bubjeongdong_level,

      b1_0.bubjeongdong_name,

      b1_0.is_close

      from

      bubjeongdong b1_0

      where

      b1_0.bubjeongdong_code=?

답변 1

1

y2gcoder님의 프로필 이미지

2023. 08. 03. 10:19

안녕하세요. awdsza님

도움을 드리고 싶지만 질문 내용만으로는 답변을 드리기 어렵습니다.

코드 예시와 함께 이해하고 계신 내용을 조금 더 풀어서 설명해주시겠어요?

안녕하세요 DB Connection 설정 테스트 하고나서 해당 영상을 보고 테스트 코드 까지 작성하고나서 Entity와 Repository DDL을 변경하고나서 이전 테이블의 칼럼내용으로 조회가 되서 질문 드립니다.


지금 올려주신 내용들에 따르면 DDL대로 테이블이 잘 생성된 것으로 보입니다. 코드와 로그도 일치한 것으로 보입니다. 어떤 부분에서 잘못되었다는 것인지 조금만 더 풀어서 설명해주시면 감사하겠습니다 :)

 

감사합니다.

awdsza님의 프로필 이미지
awdsza
질문자

2023. 08. 03. 12:26

안녕하세요. 아래에 내용이 잘못된 내용이 있었네요. 위에 질문이 있는 DDL은 이전 버전의 DDL입니다.

지금 DDL이 아래와 같습니다.

CREATE TABLE bubjeongdong (

bubjeongdongLevel int NOT NULL,

bubjeongdongCode varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,

bubjeongdongName varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,

isClose varchar(255) NOT NULL,

PRIMARY KEY (`bubjeongdongCode`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

일단 application.yml에서 ddl-auto 속성값은 none으로 설정하면 테이블이 자동적으로 안만들어 진다고 해서 해당부분은 확인했고, DDL을 직접 설정을 한 상태입니다.

테스트 코드는 아래와 같습니다.

Bubjeongdong bubjeongdong = bubjeongdongRepository.find("1156011000");

org.assertj.core.api.Assertions.assertThat(bubjeongdong.getBubjeongdongCode()).isEqualTo("1156011000");

그리고 에러 메시지 내용은 다음과 같습니다.

Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'b1_0.bubjeongdong_code' in 'field list'

at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121)

at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916)

at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:972)

at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)

at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)

at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.executeQuery(DeferredResultSetAccess.java:239)

... 123 more

제가 궁금한건 기존 테이블을 재삭제하고 해당 테이블을 다시만든다음, 테스트코드를 재실행시켜서 위와 같은 오류가 납니다.

y2gcoder님의 프로필 이미지

2023. 08. 03. 13:02

감사합니다.

JPA 엔티티와 테이블이 제대로 매핑이 되지 않는 것 같습니다. 보통 자바 클래스명, 자바 변수명(여기서는 엔티티의 필드명일 것 같습니다), 그리고 DB 테이블명과 테이블의 컬럼명은 관례가 있습니다.

자바에서 클래스의 멤버 변수 등은 모두 카멜 케이스(ex. bubjeongdongLevel)로 짓는 것이 관례입니다. 또한 DB 테이블의 컬럼명은 스네이크 케이스(ex. bubjeongdong_level)로 짓는 경우가 많습니다. 그리고 JPA는 해당 관례에 맞춰 엔티티 클래스와 테이블을 매핑해주는 것이 기본입니다.

변경한 DDL에서는 컬럼명들을 전부 스네이크 케이스로 생성하셨기 때문에, JPA 엔티티와 매핑해주는데 실패한 것으로 보입니다. 이를 해결하기 위해서는 두 가지 방법이 있습니다.

  1. @Column의 name 속성을 이용해서 매핑할 db column을 설정해줍니다.

  2. 전체 애플리케이션의 매핑 전략을 변경합니다.

이 중 2번째를 하고 싶으시다면

spring:
  jpa:
    hibernate:
      naming:
        implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

application.yml에 해당 설정을 추가해주십시오! 대신 해당 방법은 전체 매핑 전략을 변경하는 것이기 때문에, 모든 DB 테이블의 컬럼을 카멜 케이스로 설정해주셔야 합니다!

awdsza님의 프로필 이미지
awdsza
질문자

2023. 08. 09. 07:16

잘해결 되었습니다 답변감사합니다.!

y2gcoder님의 프로필 이미지

2023. 08. 09. 08:48

파이팅입니다!

awdsza님의 프로필 이미지

작성한 질문수

질문하기