스프링부트 프로젝트 도중 JPA 사용 중에 위와 같은 예외가 발생했습니다.
org.hibernate.HibernateException: More than one row with the given identifier was found: 1, for class
결론적으로 연관관계 매핑을 잘못했었고, 연관관계를 수정하니 해결했습니다. 그럼 어떤 것이 문제였는지 알려드리겠습니다.
저는, 장바구니를 구현했습니다. 장바구니와 회원의 관계는 1:1 매핑으로, 장바구니와 상품과의 관계는 多:1 관계로 매핑했습니다. 제 생각으로는 회원 A는 하나의 장바구니만 갖을 수 있고, 장바구니도 A와 B의 공동 장바구니란 개념은 없으며, A만의 장바구니 B만의 장바구니만 갖을 수 있다 생각해서였습니다. 또 회원 엔티티는 회원에 관련된 정보만 넣고 싶었기 때문에 연관 관계 주인을 장바구니에 넣었습니다.
@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Wishlist {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "wishlist_id")
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id")
private Item item;
private int selectedQuantity;
}
그래서 위와 같은 엔티티를 설계했습니다.
엔티티 설계도 끝났겠다, 저는 신나게 장바구니 API를 만들었습니다. 그런데 문제가 발생합니다. 장바구니에 상품을 두 개 이상부터 담았을 때부터 문제가 일어난 것입니다. 이 포스팅의 제목, org.hibernate.HibernateException 예외가 터진 것이죠.
문제에 대해 한참 고민을 하던 도중, 순간 아뿔싸! 하고 맙니다. 제가 했던 장바구니와 회원의 1:1 관계 설정이 문제였습니다. 장바구니에 물건을 1개 담으면 문제가 없었지만, 2개의 상품을 담게 되자 상품의 item_id와 회원의 member_id가 두 번 들어가게 되었던 것입니다.
장바구니 기준으로 회원과의 관계가 1:1 관계가 아닌 1:多관계가 되버린 것이죠.
그래서 다음과 같이 리펙토링을 진행했습니다.
public class Wishlist {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "wishlist_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id")
private Item item;
private int selectedQuantity;
}
예외만 잘 보면 문제를 해결할 수 있다. 그런데 그건 너무 어려운 일이다... ㅠ-ㅠ
'Spring Data' 카테고리의 다른 글
NoSuchMethodException - Querydsl에서 생성자 예외가 발생할 때 해결 방법 (0) | 2023.02.27 |
---|---|
Entity는 기본형 타입과 래퍼클래스 중 어떤 것을 사용하는가? (0) | 2023.01.29 |