[SpringBoot] 다대다 매핑

Ming·2023년 1월 19일
0

서론


동기부여를 위한 챌린지 서비스에서 사용자가 챌린지를 생성하기도 하고 이미 존재하는 챌린지에 참여를 할 수도 있다. 이 때 유저와 챌린지 테이블간의 다대다 관계가 발생했다.
다대다 관계는 서로가 서로를 맵핑하기 때문에 단순하게 서로가 서로를 갖도록 구현하면 JPA에서 여러가지 에러가 발생하게 된다.

해결


중간 테이블을 생성해서 N:M 관계를 1:N, M:1로 분리시켰다. 즉, 유저와 챌린지의 관계를 중간에 참여 테이블을 생성해서 유저와 참여, 참여와 챌린지 테이블로 나누게 된다.
챌린지 테이블에서는 챌린지의 정보만 갖게 되고 참여테이블에서는 어떤 유저가 어떤 챌린지를 참여하고 있는지를 관리하도록 했다.

Challenge

@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
@Where(clause="deleted_at is NULL")
public class Challenge {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;
    private String description;
    private boolean vigibility;
    @Enumerated(EnumType.STRING)
    private AuthenticationType authenticationType;

    private Long userId;

    private LocalDate startDate;
    private LocalDate endDate;

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime modifiedAt;

    private LocalDateTime deletedAt;

	//...
}

User

@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String email;

    private String picture;

    private String oauthId;

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

    //...
}

Participation

@Entity
@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class Participation {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="user_id")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="challenge_id")
    private Challenge challenge;

    //...
}

0개의 댓글