❗️시간이 얼마 없으니 메모하면서 일단 구현해보고 ‘문제 해결’ 이 아닌 내 노션에 기록 후 ‘학습’ 으로 이동!


러닝크루 기능을 모두 구현하고 참여자 기능을 구현하기 위해 Participant 테이블을 생성하였다. 하나의 러닝크루에 여러 명의 참여자가 존재하는 구조이다. (1:N)

테이블을 생성하고 엔티티를 구성하였다. 테이블 상에서는 Participant 가 N 이므로 Participant 에 RunningCrew 의 아이디가 포함되어 있지만 앞으로 구현할 기능들을 생각해보면 RunningCrew 에서 Participant 를 관리하는 편이 좋겠다고 생각하였다. 그래서 엔티티 간의 연관관계는 RunningCrew 기준으로 일대다 단방향으로 결정하였다.

RunningCrew.java

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

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

		...

		@Embedded
    private Participants participants;

		...
}

Participants.java

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Embeddable
public class Participants {

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "running_crew_id")
    private List<Participant> value = new ArrayList<>();

		...
}

Participant.java

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

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

    @Column
    private Long memberId;

    @Enumerated(value = EnumType.STRING)
    private ParticipantType status;

		...
}

간단하게 연관관계를 구성하고 실제로 값을 저장하는 로직을 구현해보았는데 다음과 같은 에러가 발생하였다.

java.sql.SQLException: Field 'running_crew_id' doesn't have a default value

내가 의도한대로 외래키는 RunningCrew 에서 관리하지만 Participant 라는 테이블에 running_crew_id 라는 FK 가 포함되어 있는 상태로, 테이블들은 올바르게 생성되었다. 하지만 running_crew_id 에 값이 없다는 에러가 발생하였다. 즉, 두 엔티티는 연관관계로 맺어져 있는데 그 외래키의 값이 설정되지 않았다는 의미이다.

에러가 발생한 컬럼의 값을 지정하려고 보니 엔티티의 구조상 불가능한 상황이었다. Participant 의 객체 내에서는 RunningCrew 에 대한 정보가 전혀 없다. 그래서 RunningCrew 를 저장할 때 외래키의 값도 설정해주어야 한다. 하지만 외래키의 값은 RunningCrew 의 아이디이므로 일단 RunningCrew 가 저장되어야 한다. 근데 RunningCrew 를 저장할 때 외래키가 자동으로 저장되지는 않는다.. 결론은 불가능이었다.

그래서 처음 설계한 엔티티의 구조가 잘못되었다고 생각하여 연관관계 자체를 바꾸어보았다.

일대다 양방향

일대다 단방향에서는 Participant 엔티티에서 RunningCrew 에 대한 정보가 전혀 없기 때문에 저장된 RunningCrew 의 아이디를 따로 설정할 수 없었다. 그래서 연관관계는 현재 그대로 유지하되, Participant 에서도 RunningCrew 정보를 추가하여 양방향으로 만들어주었다.

Participant.java