❗️시간이 얼마 없으니 메모하면서 일단 구현해보고 ‘문제 해결’ 이 아닌 내 노션에 기록 후 ‘학습’ 으로 이동!
러닝크루 기능을 모두 구현하고 참여자 기능을 구현하기 위해 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