Trouble Shooting

JungWooLee·2022년 8월 10일
0

SpringBoot ToyProject

목록 보기
5/14
post-thumbnail

발견 시점

OAuth 에 대한 테스트중 다음과 같은 에러를 발견

발생 시점은 google에 로그인 하기위해 oauth 로 redirect 하는 과정에서 발생
분석 결과 해당 sql 쿼리를 실행하였으나 반복된 에러로 redirect 최대 시도 회수를 초과하는 문제

http://localhost:8080/login?error

ERROR 13640 --- [nio-8080-exec-9] o.h.e.jdbc.spi.SqlExceptionHelper        : Syntax error in SQL statement "select user0_.id as id1_1_, user0_.created_date as created_2_1_, user0_.modified_date as modified3_1_, user0_.email as email4_1_, user0_.name as name5_1_, user0_.picture as picture6_1_, user0_.role as role7_1_ from [*]user user0_ where user0_.email=?"; expected "identifier"; SQL statement:
select user0_.id as id1_1_, user0_.created_date as created_2_1_, user0_.modified_date as modified3_1_, user0_.email as email4_1_, user0_.name as name5_1_, user0_.picture as picture6_1_, user0_.role as role7_1_ from user user0_ where user0_.email=? [42001-212]

처음에는 User 엔티티의 Id 를 생성하는 GenerationType.IDENTITYGenerationType.IDENTITY 의 문제인줄 알고 h2 db 문법이 이를 인식하지 못하는 문제로 생각하였다

즉, Dialect 문제인가 하여 properties 를 변경해보았다

application.properties 설정 추가

#h2 db 설정
spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

#hibernate 설정
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.hibernate.ddl-auto=create


spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.properties.hibernate.dialect.storage_engine=innodb

이를 통해 확인결과 sql 쿼리문의 문제가 아닌 근본적인 문제가 있음을 발견

Hibernate: 
    
    drop table if exists restaurant
Hibernate: 
    
    drop table if exists user
[2022-08-10 13:40:08:2997] WARN  32520 --- [           main] o.h.t.s.i.ExceptionHandlerLoggedImpl     : GenerationTarget encountered exception accepting command : Error executing DDL "
    drop table if exists user" via JDBC Statement

위를 통해 알 수 있듯 사실 user 테이블 자체가 생성되지 않았으며 에러가 발생되었음을 알수 있습니다

restaurant 테이블과 user 테이블과는 어떤 차이?

우선 restaurant 와 user 의 큰 차이점이라고 본다면 두가지가 있습니다
Pk 생성시 restaurant는 스크래핑 과정에서 이미 고유한 id 값을 삽입받을 수 있기때문에 따로 GenerationType을 지정하지 않았지만 user 테이블은 auto_increment를 추가하여 주었습니다

다음으로 큰 차이점은 테이블명입니다

처음 에러를 발견하였을 때 주요하게 본점은 expected "identifier"; 라는 구문입니다.
이는 유일하지 않다? 라고 해석되어 id 값을 인식하지 못하는 것으로 접근하였는데 그게 아니라 테이블명의 unique가 보장되지 않음을 이해하게 되었습니다

즉, User 이라는 단어가 SQL의 키워드 중 하나이기 때문에 쓸 수 없다 로 결론 지을 수 있습니다

그렇기에 다음과 같이 테이블명을 users 로 바꾼뒤 확인해봅니다

@Getter
@NoArgsConstructor
@Table(name="users")
@Entity
public class User extends BaseTimeEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String email;

    @Column
    private String picture;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private Role role;

    @Builder
    public User(String name, String email, String picture, Role role) {
        this.name = name;
        this.email = email;
        this.picture = picture;
        this.role = role;
    }

    public User update(String name, String picture){
        this.name = name;
        this.picture = picture;
        return this;
    }

    public String getRoleKey(){
        return this.role.getKey();
    }
}

로그를 통해 확인결과 생성시 문제가 없음을 알 수 있습니다

OAuth 로그인 또한 성공적으로 담김을 알 수 있습니다

0개의 댓글