일대다 (1:N)
관계는 다대일 관계의 반대 방향입니다.
일 (1)
이 외래키를 관리하며, 연관관계의 주인 입니다.
해당 관계는 표준 스펙에서 지원은 하지만, 실무에서 권장하지 않는 관계 입니다.
일대다 연관관계를 사용하여 발생하는 문제점들을 통해서 그 이유를 알아보도록 하겠습니다.
이해를 돕기 위해, 회원(N, Member)과 팀(1, Team)의 관계를 예시로 들어보겠습니다.
위 테이블 모델링 조건에 일대다 단방향 관계를 위한 추가 조건은 아래와 같습니다.
위 객체 모델링을 보면, 테이블 모델링 상 외래키를 소유하고 있는 MEMBER 테이블의 반대편인 TEAM 테이블의 객체인 Team 클래스가 외래키를 관리하고 있는 특이한 모습입니다.
해당 객체 모델링을 코드로 나타내어 보도록 하겠습니다.
Team 클래스 (일대다
에서 일
에 해당합니다.)
@Entity
public class Team {
@Id
@Column(name = "TEAM_ID")
private Long id;
@Column(name = "NAME")
private String name;
@OneToMany
@JoinColumn(name = "TEAM_ID") // MEMBER 테이블의 TEAM_ID (FK)
pricate List<Member> members = new ArrayList<>();
// Getter, Setter, Constructor, ...
}
Member 클래스 (일대다
에서 다
에 해당합니다.)
@Entity
public class Member {
@Id
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
// Getter, Setter, Constructor
}
일대다 단방향
매핑에서는 일
에 해당하는 클래스에 다
에 해당하는 클래스를 Collection 프레임워크로 감싼 형태의 참조 필드로 작성해주시면 됩니다.
이때, 해당 참조 필드위에 @OneToMany
와 @JoinColumn(name = "외래키 이름")
을 추가하여 줍니다.
외래키를 매핑할 때 사용합니다.
자세한 속성은 JPA 단방향 연관관계 에 있는 설명과 동일합니다.
일대다 단방향 관계를 매핑할 때는 @JoinColumn을 명시해야 합니다.
그렇지 않으면 JPA 는 연결 테이블을 중간에 생성하고, 연관관계를 관리하는 조인 테이블 전략을 기본으로 사용하여 매핑합니다.
일대다 관계에서 사용합니다.
속성 | 기능 | 기본값 |
---|---|---|
optional | false로 설정하면 연관된 엔티티가 항상 있어야 한다 | true |
mappedBy | 연관관계의 주인 필드를 선택한다. | |
fetch | 글로벌 패치 전략을 설정한다. (자세한 내용은 추후에) | @ManyToOne=FetchType.EAGER (즉시 로딩), @OneToMany=FetchType.LAZY (지연 로딩) |
cascade | 영속성 전이 기능을 사용한다. (자세한 내용은 추후에) | |
orphanRemoval | true 로 설정 시, 고아 객체를 즉시 삭제합니다. | false (고아 객체를 삭제하지 않습니다.) |
targetEntity | 연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거의 사용하지 않음 |
연관관계를 등록, 삭제 하는 예제를 통해 연관관계를 어떻게 사용하는지 알아보겠습니다.
Member member1 = new Member(0L, "회원1");
Member member2 = new Member(1L, "회원2");
entityManager.persist(member1); // INSERT-MEMBER1
entityManager.persist(member2); // INSERT-MEMBER2
Team team1 = new Team(0L, "팀1");
team1.getMembers().add(member1);
team1.getMembers().add(member2);
entityManager.persist(team1); // INSERT-TEAM1, UPDATE-MEMBER1.FK, UPDATE-MEMBER2.FK
INSERT INTO MEMBER (MEMBER_ID, USERNAME) VALUES (0, '회원1');
INSERT INTO MEMBER (MEMBER_ID, USERNAME) VALUES (1, '회원2');
INSERT INTO TEAM (TEAM_ID, NAME) VALUES (0, '팀1');
UPDATE MEMBER SET TEAM_ID = 0 WHERE MEMBER_ID = 0;
UPDATE MEMBER SET TEAM_ID = 0 WHERE MEMBER_ID = 1;
실행되는 SQL 코드를 보면 @OneToMany 단방향 매핑의 단점을 알 수 있습니다.
해결법은 우선 다대일 단방향 매핑으로 테이블 모델링과 일치시켜준 후, 필요에 따라 일대다 단방향 매핑을 추가한 다대일 양방향 매핑을 사용합니다.
orphanRemoval 옵션을 true 로 하여 고아 객체를 어떻게 관리하는지 살펴보겠습니다.
Team team = entityManager.find(Team.class, 0L);
entityManager.remove(team);
UPDATE MEMBER SET TEAM_ID = null WHERE TEAM_ID = 0;
DELETE FROM MEMBER WHER MEMBER_ID = 0;
DELETE FROM MEMBER WHER MEMBER_ID = 1;
DELETE FROM TEAM WHER MEMBER_ID = 0;
고아객체 삭제 옵션을 사용하였기 때문에, team 객체의 삭제로 인하여 고아객체가 되어버린 member 객체 역시 삭제되었습니다.
이런 매핑은 공식적으로 존재하지 않습니다..
대신 다대일 양방향 매핑을 사용하도록 하자 (일대다 양방향 == 다대일 양방향)
일(1), 다(N) 관계에서는 항상 다(N)에 외래키가 있으므로 @OneToMany, @ManyToOne 둘 중에 연관관계의 주인은 항상 다 쪽인 @ManyToOne 입니다.
- 이런 이유로 @ManyToOne 에는 연관관계의 주인을 설정해주는 mappedBy 속성이 존재하지 않습니다..
그렇다고 일대다 양방향 매핑이 완전히 불가능한 것 은 아닙니다.
일(1)
(Team) 입니다.해당 객체 모델링을 코드로 나타내어 보도록 하겠습니다.
Team 클래스 (일대다
에서 일
에 해당합니다.)
@Entity
public class Team {
@Id
@Column(name = "TEAM_ID")
private Long id;
@Column(name = "NAME")
private String name;
@OneToMany
@JoinColumn(name = "TEAM_ID") // MEMBER 테이블의 TEAM_ID (FK)
pricate List<Member> members = new ArrayList<>();
// Getter, Setter, Constructor, ...
}
Member 클래스 (일대다
에서 다
에 해당합니다.)
@Entity
public class Member {
@Id
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID", insertable = false, updatable = false)
private Team team;
// Getter, Setter, Constructor
}
@ManyToOne과 @JoinColumn을 사용해서 연관관계를 매핑하면, 다대일 단방향 매핑이 되어버립니다. 그런데 반대쪽 Team에서 이미 일대다 단방향 매핑이 설정되어있습니다.
이런 상황에서는 두 엔티티에서 모두 테이블의 FK 키를 관리 하게 되는 상황이 벌어집니다.
그걸 막기 위해서 insertable, updatable 설정을 FALSE로 설정하고 읽기 전용 필드로 사용해서 양방향 매핑처럼 사용하는 방법입니다.
위 방법은 일대다 양방향 매핑이라기 보다, 일대다 단방향 매핑 반대편에 다대일 단방향 매핑을 읽기 전용으로 추가하여 일대다 양방향 처럼 보이게 하는 방법입니다.
결론은 다대일 양방향을 사용하면 편합니다.
Enjoy every moment with elite Escorts Daryaganj, where your comfort and pleasure are the top priorities. These elegant companions know how to create perfect memories through charm, care, and sensuality. Whether you want a one-time thrill or regular indulgence, their quality service ensures you leave satisfied. Book now for magical moments.