본문 바로가기
Spring Data

HibernateException 예외 해결 - JPA 연관관계 매핑에서 발생한 문제 해결 방법

by 코더 제이콥 2023. 2. 25.

스프링부트 프로젝트 도중 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;
}

 

예외만 잘 보면 문제를 해결할 수 있다. 그런데 그건 너무 어려운 일이다... ㅠ-ㅠ