일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 스프링 데이터 JPA
- 연관관계 매핑
- rest api
- NAMED 쿼리
- 뷰 템플릿
- 스프링
- 지연로딩
- JPQL
- hibernate5Module
- 컬렉션 조회
- HTTP API
- JPA
- 엔티티 매핑
- DTO 조회
- API
- 한방 쿼리
- 페치 조인
- batchsize
- 정적 리소스
- 주문조회
- 엔티티 변환
- 성능 최적화
- 서블릿
- SpringEL
- dto
- MVC
- querydsl
- 벌크 연산
- 서버인증
- DB
Archives
- Today
- Total
UmaiCo - 우마이코
[오류해결] JdbcSQLSyntaxErrorException 본문
개인 프로젝트를 진행하다 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
와 연관관계를 가지고 있음)
'ToyProject > Health Community' 카테고리의 다른 글
생성자에서 빌더로 변환 (0) | 2023.03.21 |
---|---|
[오류해결] UnexpectedRollbackException (0) | 2023.03.06 |
[의문점] @MappedSuperclass vs Embedded Type (0) | 2023.03.04 |