@Data
@Entity
@NoArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public Member(Long id) {
this.id = id;
}
public Member(String name) {
this.name = name;
}
}
@Data
@Entity
@NoArgsConstructor
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "member_id")
private Member member;
public Team(Member member) {
this.member = member;
}
}
객체를 활용한 JPA 연관관계 사용
@Service
@RequiredArgsConstructor
public class TeamService {
private final TeamRepository teamRepository;
private final MemberRepository memberRepository;
@Transactional
public void save(Long memberId) throws NotFoundException {
Member member = memberRepository.findById(memberId).orElseThrow(NotFoundException::new);
Team team = new Team(member);
teamRepository.save(team);
}
}
위의 코드는 Spring을 처음하는 사람에게 가장 익숙할 수 있는 JPA 연관관계를 사용하는 코드이다.
위의 코드를 사용하며 아래와 같은 sql 쿼리가 생성된다.
Hibernate:
select
member0_.id as id1_0_0_,
member0_.name as name2_0_0_
from
member member0_
where
member0_.id=?
Hibernate:
insert
into
team
(member_id)
values
(?, ?)
내가 하고 싶은 건 Team을 저장하는 것인데 member 조회 쿼리까지 나가는 겁니다.
불필요한 쿼리를 없애고자
연관관계를 엔티티가 아닌 Id로 하고자 합니다.
@Data
@Entity
@NoArgsConstructor
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long memberId;
public Team(Long memberId) {
this.memberId = memberId;
}
}
@Service
@RequiredArgsConstructor
public class TeamService {
private final TeamRepository teamRepository;
private final MemberRepository memberRepository;
@Transactional
public void save(Long memberId) {
Team team = new Team(memberId);
teamRepository.save(team);
}
}
Hibernate:
insert
into
team
(member_id)
values
(?, ?)
이렇게 된다면 저희에게 필요한 team 저장하는 쿼리만 나가게 됩니다.
단점
- 데이터 무결성이 보장이 안된다.
- DDD 같은 경우는 루트엔티티가 내부의 객체들을 관리하기 때문에 무결성이 보장이 된다.
- 그러나 DDD가 아닌 경우 데이터 무결성이 보장이 안된다
- 또한 관리가 복잡할 수도 있다
- 예를 들면 member가 삭제되면 team도 삭제되어야 한다. 엔티티로 연관관계를 지을 경우 자동으로 삭제된다. 그러나 Id로 연관관계를 할 경우 직접 삭제한 memberId를 가지고 있는 team을 찾아 삭제해야 한다.
엔티티 연관관계와 id로 연관관계 중 어떤 게 실무에 적합해 보이나요?
'스프링' 카테고리의 다른 글
Intellij 설정 (0) | 2024.04.16 |
---|---|
HTTP 메소드 PUT, FATCH 차이점(멱등성) (0) | 2024.04.11 |
@NoArgsConstructor(access = AccessLevel.PROTECTED) 쓰는 이유 (0) | 2024.04.06 |
Intellij에서 gradle 버전이 안 보일 때 해결법 (0) | 2024.04.06 |
mysql, gradle 종속성 관리 변경된 점 (0) | 2024.01.31 |