UmaiCo - 우마이코

[오류해결] JdbcSQLSyntaxErrorException 본문

ToyProject/Health Community

[오류해결] JdbcSQLSyntaxErrorException

코드 미식가 2023. 3. 5. 11:27

개인 프로젝트를 진행하다 jdbcsqlsyntaxerrorexception에 직면했다.

바로

package project.healthcommunity.domain;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static java.util.Arrays.*;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "trainerName", "age", "career"})
public class Trainer extends BaseEntity {

    @Id
    @GeneratedValue
    @Column(name = "trainer_id")
    private Long id;

    private String trainerName;
    private int age;
    private int career;


    @OneToMany(mappedBy = "trainer", cascade = CascadeType.ALL)
    private List<Certificate> certificates = new ArrayList<>();

    private int ranking;

    @OneToMany(mappedBy = "trainer", cascade = CascadeType.ALL)
    private List<Post> postList = new ArrayList<>();

    //생성자 생략
    //비지니스 로직 생햑

}

위와같이 트레이너 테이블을 작성했다.


이후 DB에 정상적으로 들어가는지 Test케이스를 작성하다

트레이너를 delete하는 과정에서 jdbcsqlsyntaxerrorexception가 발생하였다.



jdbcsqlsyntaxerrorexception가 무엇인지 살펴보니 DB연결에 문제가 있거나, 엔티티가 DB예약어를 사용하는 문제로 발생하는 것 같았다.  

하지만 DB연결에는 문제가 없었고, DB예약어를 사용한 적을 없었다.  

위의 이유뿐만이 아니라 jdbcsqlsyntaxerrorexception, 말그대로 jdbcSQL문법에 오류가 있다는 뜻으로 받아들였다.  

즉 delete문에 오류가 있다는 소리이다.  


delete에 영향을 받는 필드들을 살펴보니, certificates와 postList의 cascade타입을 ALL로 설정한것이다.  

cascade는 전이라고도 하는데, 전이는 @OneToMany, @OneToOne일때 사용하는데, 이경우 certificates와 postList 모두 @OneToMany로 상관없다.  

그래서 certificates의 전이 속성을 없애고 삭제문을 날려보고, postList의 전이 속성을 없애고 삭제문을 날려보았다.  

그랬더니 postList의 전이 속성을 지웠을 때만 정상적으로 삭제문이 작동하였다.  


certificates와 postList의 차이를 곰곰히 생각해보았다.  

잘 생각해보니 certificates는 트레이터 엔티티만이 참조(연관관계)하였고,  

postList는 트레이너 뿐만 아니라 다른 곳에서도 참조(연관관계)가 있었다.   

그래서 예전에 정리해놓았던 전이에 대한 내용을 읽어보니, 참조하는 곳이 하나일때, 즉 특정 엔티티가 해당 엔티티를 개인 소유할때만 사용하는 것이 바람직하다고 적혀있다.  

아무래도 postList가 트레이너만 소유한것이 아니라 발생한 상황인 것 같다.

postList의 전이 속성을 없애버렸다.  
package project.healthcommunity.domain;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Post extends BaseEntity{

    @Id
    @GeneratedValue
    @Column(name = "post_id")
    private Long id;

    private String title;

    private String content;

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
    private List<Comment> comments = new ArrayList<>();

    private int like;

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
    private List<CategoryPost> categoryList = new ArrayList<>();

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "trainer_id")
    private Trainer trainer;

    @Enumerated(EnumType.STRING)
    private PostStatus status;

    //생성자 생략
    //비지니스 로직 생햑
}


정리

  • cascade = CascadeType.ALL이 원인

트레이너 테이블에서

  • List 에 CascadeType.ALL 적용 가능(종속적임)

  • List 에는 불가능(다른 엔티티 Member 와 연관관계를 가지고 있음)