복합키에서는
@GeneratedValue
를 통해 기본키를 자동생성할 수 없다
복합키 - @GeneratedValue 시리즈는 위의 주장을 반박하기 위해서 쓴 포스트이다.
@IdClass
를 사용하면 @GeneratedValue
를 사용할 수 있음을 내 포스트에서 밝혔다.
그렇다면 @EmbeddedId
를 사용해도 @GeneratedValue
를 사용할 수 있을까?
결론을 말하자면 @EmbeddedId 경우 사용할 수 없다가 내 주장이다.
물론 항상 가능성을 열어두고자 한다. 나의 주장임을 알아주었음 한다.
실험한 코드는 다음과 같다.
// 부모
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Parent2 {
@SequenceGenerator(
name = "parent_id_seq2",
sequenceName = "parent_id_seq2",
allocationSize = 1
)
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "parent_id_seq2")
private Long id;
private String name;
public Parent2(String name) {
this.name = name;
}
}
// 자식
@Entity
public class Child2 {
@EmbeddedId
private ChildId childId;
private String name;
@MapsId("parentId")
@ManyToOne
@JoinColumn(name = "PARENT_ID")
private Parent2 parent;
@Data
@NoArgsConstructor
@Embeddable
public static class ChildId implements Serializable {
private Long parentId;
@SequenceGenerator(
name = "child_id_seq2",
sequenceName = "child_id_seq2",
allocationSize = 1
)
@Column(name = "CHILD_ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "child_id_seq2")
private Long id;
}
}
@Entity
public class Child2 {
@EmbeddedId @GeneratedValue
private ChildId childId;
@Embeddable
public static class ChildId implements Serializable {
private Long parentId;
@Column(name = "CHILD_ID")
private Long id;
}
}
맨 처음에 위의 방식대로 생각을 했었다.
그런데 위의 방식대로 하는 경우 childId에는 2개의 아이디가 있는데 어디에 아이디를 자동할당할 것인지 불분명해보였다.
@Entity
public class Child2 {
@EmbeddedId
private ChildId childId;
@Embeddable
public static class ChildId implements Serializable {
private Long parentId;
@GeneratedValue
@Column(name = "CHILD_ID")
private Long id;
}
}
parentId
는 이미 Parnet2에서 자동할당 받았을 것이므로 그럼 나머지 부분인id
만 자동할당받으면 될 것이므로 두번째 방식을 택하게 되었다.
다음과 같이 테스트코드를 작성하여 진행하였다.
@Test
@DisplayName("insert Test")
public void insertTest() throws Exception {
Parent2 parent = new Parent2("부모");
Parent2 saveParent = parentRepository.save(parent);
Child2.ChildId childId = new Child2.ChildId();
childId.setParentId(saveParent.getId());
Child2 child = Child2.builder()
.name("자식")
.parent(saveParent)
.childId(childId)
.build();
childRepository.save(child);
}
그러니 다음과 같은 결과가 나왔다.
null값이 들어간걸로 보아 @GeneratedValue
가 먹히지 않음을 알 수 있다.
따라서 @EmbeddedId
의 경우 @GeneratedValue
을 사용할 수 없음을 주장하게 되었다.
포스팅의 전체적인 코드는 깃헙코드에서 볼 수 있다.