@JoinColumns 이슈

PPakSSam·2022년 1월 11일
0

목차


@JoinColumns 이슈


식별관계 구현

[Parent]

@Entity
public class Parent {
    
    @Id
    @Column(name = "PARENT_ID")
    private String id;
    private String name;
    ...
}

[Child]

@Entity
public class Child {
    
    @EmbeddedId
    private ChildId id;
  
    @MapsId("parentId")
    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private Parent parent;
  
    private String name;
    ...
}

@Embeddable
public class ChildId implements Serializable {
    
    @Column(name = "CHILD_ID")
    private String id;
  
    private String parentId;
    ...
}

[GrandChild]

@Entity
public class GrandChild {
    
    @EmbeddedId
    private GrandChildId id;
  
    @MapsId("childId")
    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "PARENT_ID"),
            @JoinColumn(name = "CHILD_ID")
    })
    private Child child;
  
    private String name;
    ...
}
  
@Embeddable
public class GrandChildId implements Serializable {
    
    private ChildId childId;
    
    @Column(name = "GRANDCHILD_ID")
    private String id;
    ...
}

[JpaMain]

Parent parent = new Parent();
parent.setId("parentId");
parent.setName("부모");
em.persist(parent);

ChildId childId = new ChildId();
childId.setId("childId");
childId.setParentId("parentId");

Child child = new Child();
child.setId(childId);
child.setParent(parent);
child.setName("자식");
em.persist(child);

GrandChildId grandChildId = new GrandChildId();
grandChildId.setId("grandChildId")
grandChildId.setChildId(childId);

GrandChild grandChild = new GrandChild();
grandChild.setId(grandChildId);
grandChild.setChild(child);
grandChild.setName("손자");
em.persist(grandChild);

위의 코드를 실행 후 테이블에 삽입된 데이터는 아래와 같다.



오류 발견

GRAND_CHILD 테이블에 PARENT_ID 컬럼과 CHILD_ID 컬럼 값이 바뀌어 삽입되었다.


오류 원인

@JoinColumns를 사용시에는 referencedColumnName을 지정하지 않으면 INSERT시 @JoinColumns@JoinColumn 선언 순서에 따라 값이 바뀌어 삽입되어 문제가 발생할 수 있다.

실제로 @JoinColumns JavaDoc을 확인해 보면 해당 내용이 언급되어 있다.


오류 해결

@Entity
public class GrandChild {
    
    @EmbeddedId
    private GrandChildId id;
  
    @MapsId("childId")
    @ManyToOne
    @JoinColumns({
          @JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID"),
          @JoinColumn(name = "CHILD_ID", referencedColumnName = "CHILD_ID")
    })
    private Child child;
  
    private String name;
    ...
}

@JoinColumns JavaDoc에서 권고하는 대로 referencedColumnName을 지정하면 된다.

결론

@JoinColumns를 사용시에는 @JoinColumnreferencedColumnName을 지정하자.

참고

profile
성장에 대한 경험을 공유하고픈 자발적 경험주의자

0개의 댓글