글로벌 패치 전략 설정

즉시로딩과 지연로딩을 잘 적용하여 사용하는 것이 효율성과 최적화의 관점에서 중요하다.

예를 들어 사내 주문 관리 시스템을 개발한다고 할 떄,

김영한이 쓰신 jpa orm 표준 JPA 프로그래밍이라는 책에서 추천하는 방법은 모든 연관관계에 지연 로딩을 사용하고 애플리케이션 개발이 어느 정도 완료 단계에 왔을 때 실제 사용하는 상황을 보고 꼭 필요한 곳에만 즉시 로딩을 사용하도록 최적화하는 것이다.

실무에서도 시스템 규모가 커진다면 개발자가 예상치 못한 정도로 많은 SQL문이 만들어질 수 있기 때문에 지연 로딩을 지향한다고 한다.

@OneToMany, @ManyToMany는 기본이 지연 로딩이므로 그냥 두고 @OneToOne, @ManyToOne의 fetch 속성을 지연 로딩으로 수정해볼 것.

현재 프로젝트 코드에서, @ManyToOne과 @OneToOne이 적용된 부분이 거의 다 fetch=FetchType.EAGER로 지정되어 있길래 이 부분을 다 fetch = FetchType.LAZY로 바꿔주었다.

@NoArgsConstructor
@AllArgsConstructor
@Entity
@Getter
@EntityListeners(AuditingEntityListener.class)
public class LikeablePerson extends BaseEntity {

    @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @Setter
    private User fromUser;// 호감을 표시한 사람@ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @Setter
    private User toUser;// 호감을 받은 사람@CreatedDate
    private LocalDateTime createDate;

}
@Table(name = "blind_date")
@Getter
@Setter
@Entity
public class Match extends BaseEntity {

    @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private User user1;

    @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private User user2;

    @Column(name="score")
    private int compatibilityScore;

    @Builder.Default
    @Column(name="result")
    private Boolean matched = false;

}
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Chat {

    @Id @GeneratedValue
    @Column(name = "chat_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "room_id")
    private Room room;

@Entity
@Setter
@Getter
@NoArgsConstructor()
public class Room {
    @Id
    @GeneratedValue
    @Column(name ="room_id")
    private Long id;

    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @JoinColumn(name="final_match_id")
    private FinalMatch finalMatch;

}
@Table(name="final_match")
@Getter
@Setter
@Entity
@EntityListeners(AuditingEntityListener.class)
public class FinalMatch extends BaseEntity {
    @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private User user1;

    @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private User user2;

그렇다면 어떠한 경우에 즉시 로딩을 적용해야 하는 것일까 ? 꼭 사용될 것이라고 여겨지는 경우, 즉시 로딩을 사용해도 될 것 같다. 예를 들어 User와 Team이 @ManyToOne관계로 매핑되었을 때, 실제 해당 user가 team과 관려된 정보를 가져다 쓰지 않을 수 있기 때문에, 이러한 상황에서는 즉시로딩을 한 것이 의미가 없게된것이다.

영속성 전이 설정

엔티티를 영속 상태로 만들어서 데이터베이스에 저장할 때 연관된 엔티티도 모두 영속 상태여야 한다. 연관된 엔티티 중에 영속 상태가 아닌 엔티티가 있으면 flush시점에 오류가 발생하기 때문이다.