[ 예제 도메인 모델과 동작 확인 ]
1. 도메인 설계
1-1. 엔티티 클래스

1-2. ERD

2. 코드
2-1. Member
@Entity
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "username", "age"})
public class Member {
@Id
@GeneratedValue
@Column(name = "member_id")
private Long id;
private String username;
private int age;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;
public Member(String username) {
this(username, 0);
}
public Member(String username, int age) {
this(username, age, null);
}
public Member(String username, int age, Team team) {
this.username = username;
this.age = age;
if (team != null) {
changeTeam(team);
}
}
public void changeTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
}
- 실무에서는
@Setter
거의 사용하지 말자!
@NoArgsConstructor(access = AccessLevel.PROTECTED)
: JPA 스펙상 기본 생성자는 있어야 하는데, 그 외에 영역에서는 막고 싶으므로 PROTECTED
로 열어둔다.
ToString
은 가급적 내부 필드만 (연관관계 없는 필드만)
changeTeam()
으로 양방향 연관관계 한번에 처리 (연관관계 편의 메서드)
2-2. Team
@Entity
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "name"})
public class Team {
@Id @GeneratedValue
@Column(name = "team_id")
private Long id;
private String name;
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<>();
public Team(String name) {
this.name = name;
}
}
- Member와 Team은 양방향 연관관계
Member.team
이 연관관계의 주인 → 데이터베이스 외래키 값을 변경할 수 있다.
Team.members
는 연관관계의 주인 ❌ → 조회만 가능하다.