Open dtd1614 opened 1 year ago
현재의 문제 상황이 어떤지 확실하게 파악하고 계시고, 훌륭한 설명인 것 같습니다.
이렇게 쿼리가 남발된다면 성능이 저하될 것이고, One-To-One 양방향 연관 관계에서는 fetch = LAZY
로 설정하는 것에 제약이 따르는 것을 인지하였습니다.
One-To-One 양방향 연관 관계에서 주인이 아닌 Entity를 조회하면 지연 로딩이 적용되기 어렵습니다. 연관 관계를 설정할 필요가 없다고 판단하여, 제거하였습니다.
다음은, 관계의 주인 MemberGeneral
입니다.
public class MemberGeneral extends AuditEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_general_id")
private Long id;
private Long memberId;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private boolean isAuto;
}
이에 따라 MemberGeneralRepository
의 findByMemberId()
를 활용할 수 있습니다.
public interface MemberGeneralRepository extends JpaRepository<MemberGeneral, Long> {
Optional<MemberGeneral> findByMemberId(Long memberId);
boolean existsByMemberId(Long memberId);
}
보시는 바와 같이, 이제는 Member
가 아닌 memberId
를 통해서 조회하게 됩니다.
회원 관련 정보를 조회할 때, 연관 관계가 설정되어 있지 않아야 효율적이라고 판단하여 명시적으로 연관 관계를 설정하지 않았습니다.
대신, memberId
속성을 추가하여 Member
를 조회할 수 있습니다.
@OneToOne 양방향 매핑시 Fetch 전략을 Lazy로 설정해도 Eager로 동작하는 경우가 있습니다.
Member 엔티티는 MemberGeneral, MemberSocial, MemberProfile, MemberAgreement와 OneToOne으로 매핑되어 있으며, Fetch 전략을 Lazy로 설정해주었습니다.
MemberGeneral 또한 Member와 OneToOne으로 매핑되어 OneToOne 양방향 관계가 설정되었습니다. 마찬가지로 Fetch 전략을 Lazy로 설정해주었습니다. MemberSocial, MemberProfile, MemberAgreement 또한 Member와 OneToOne 양방향 관계로 매핑되어있습니다.
이제 Member를 가져왔을 때 Lazy 로딩이 잘 되는 지 테스트 해보겠습니다.
Member 하나를 먼저 저장해주고, 저장한 멤버를 불러왔을 때 쿼리가 어떻게 나가는지 확인해봤습니다.
Fetch 전략을 Lazy로 설정했음에도 Eager로 동작하는 것을 확인할 수 있습니다.
OneToOne 양방향 관계 시, Fetch 전략을 Lazy로 설정하여도 주인이 아닌 쪽, 즉 FK를 가지고 있지 않은 엔티티에서는 Lazy 로딩이 동작하지 않습니다. FK가 없으면 연관 관계 엔티티의 존재 여부를 알 수 없습니다. Lazy 로딩은 관계 엔티티를 Proxy 객체로 할당해야 하는데, FK가 없는 엔티티만 읽어서는 관계 엔티티의 존재 여부를 알 수 없으니 강제로 Eager 로딩을 수행하는 것입니다. (Proxy에 null을 할당할 수는 없습니다.) 참고 : https://jeong-pro.tistory.com/249
Member는 FK를 가지고 있지 않기 때문에 주인이 아닙니다. 테스트 코드에서 주인이 아닌 Member를 가져왔기 때문에 Lazy 로딩이 동작하지 않은 것입니다.
OneToOne 관계에서 Lazy loading 발동 조건은 다음과 같습니다. 참고 : https://velog.io/@moonyoung/JPA-OneToOne-%EC%96%91%EB%B0%A9%ED%96%A5-%EB%A7%A4%ED%95%91%EA%B3%BC-LazyLoading
Member와 MemberGeneral의 관계를 단방향으로 설정해주어 Lazy 로딩을 수행시킬 수 있을 것으로 보입니다.