@ManyToOne
@OneToMany
@OneToOne
@ManyToMany
실무에서는 쓰면 안 됨@Entity
public class Member {
// ...
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
@Entity
public class Team {
// ...
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
@Entity
public class Team {
@Id @GenerateValue
private Long id;
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
@JoinColumn
을 꼭 사용해야 함. 그렇지 않으면 조인 테이블 방식을 사용함
(중간에 테이블을 하나 추가함, TEAM_MEMBER 테이블)
Member member = new Member("member");
em.persist(member); //insert member, 외래키 team_id에는 null이 일단 들어감
Team team = new Team("A");
team.getMembers().add(member);
em.persist(team);
// team을 영속화하는 순간 team에 대한 insert 쿼리 발생
// member에 대한 insert도 발생하는데 일대다 단방향의 경우 team_id는 null로 insert
// 이후에 따로 member 테이블의 외래키(team_id)를 수정하는 update 쿼리도 나가야 함
// 양방향이었다면 insert할 때 한 번에 team_id도 넣어서 update 쿼리가 필요 없음
@JoinColumn(insertable=false, updatable=false)
컬렉션에서 필드를 미리 초기화하는 이유
- NPE 방지
- 하이버네이트가 엔티티를 영속화 할 때 내부에서 컬렉션이 있으면 하이버네이트가 특별하게 조작한 컬렉션으로 변경한다. (컬렉션의 데이터가 추가 되었는지 등등을 인식할 수 있어야 하니까) 따라서 실제 참조가 변경될 수 있다. 그런데 개발자가 임의로 나중에
new ArrayList()
로 초기화를 하게 되면 이 부분이 하이버네이트가 관리하는 컬렉션에서 개발자가 직접 만든 컬렉션으로 변경될 수 있다. 그러면 하이버네이트가 정상 동작하지 않는다. 이런 문제를 방지하기 위해 필드에서 빠르게 컬렉션을 초기화 하고, 해당 컬렉션을 바꾸는 행위를 막도록 코드를 작성하는 것이 좋다.
@OneToOne
@JoinColumn(name = "LOCKED_ID")
private Locker locker
(@ManyToOne
) 단방향 매핑과 유사@OnetoOne(mappedBy = "locker")
private Member member;
mappedBy
적용대상 테이블에 외래 키를 두고 일대일 단방향은 JPA에서 지원하지 않는다. 그리고 대상 테이블에 외래 키 양방향은 사실상 주 테이블 외래 키 양방향이랑 똑같다.
연결 테이블에 주문 시간, 수량 같은 데이터가 들어올 수 있음
다대다로 생긴 중간 테이블엔 그러한 추가 정보를 넣을 수 없음
자바 객체로는 표현되지 않기 때문
생각하지 못한 쿼리가 나감. (중간 테이블로 조인하면서)
@ManyToMany
-> @OneToMany
, @ManyToOne
연결 테이블용 엔티티의 PK를 FK를 묶어서 사용할 수도 있지만 PK는 정말 비즈니스적으로 의미 없는 값을 사용하는 것이 좋기 때문에 따로 id를 만들어서 PK로 사용하는게 유지보수성이 좋다는 영한님 의견이 있음
N:M 관계는 1:N, N:1로
@ManyToMany
는 제약: 필드 추가X, 엔티티 테이블 불일치@ManyToMany
사용Xname
: 매핑할 외래 키 이름referencedColumnName
: 외래 키가 참조하는 대상 테이블 컬럼 명foreignKey
: 외래 키 제약 조건을 직접 지정할 수 있다. 이 속성은 테이블을 생성할 때만 사용한다.unique
, nullable
, insertable
, updatable
, columnDefinition
, table
: @Column
의 속성과 같다.