중간 테이블에 컬럼을 추가할 수 없고 세밀한 쿼리가 어렵다. 대신 중간 엔티티를 만들고 @ManyToOne, @OneToMany로 매핑하자
일대다에서 다 쪽이 연관관계의 주인이다. 연관관계 주인 쪽은 기본적으로 @ManyToOne,@JoinColumn 지정한다. 반대 쪽은 @OneToMany(mappedBy = "memeber")
Setter 대신 비즈니스 메서드를 별도로 제공하자
Setter를 제거하고 생성자에서 값을 모두 초기화하자.
JPA가 객체 생성할때 리플랙션을 사용한다.
즉시 로딩으로 설정하면 N+1 문제가 자주 발생한다. @XToOne 관계는 직접 지연로딩으로 설정하자
null 문제에 안전하고 하이버네이트 특성상 초기화하지 않으면 내부 메커니즘에 문제가 발생할 수 있다.
이때 JPA는 DB로 쿼리를 날린다. flush 기능이다.
단방향 매핑만으로도 DB와 연관관계 매핑은 이미 끝이다.
객체 입장에서 양방향 매핑은 양쪽 다 신경 써야 하므로 복잡해지고 실수할 확률이 높아진다.
처음 모델링할 때는 단방향 매핑으로 설계를 끝내자
이후 양방향 매핑이 효율적이라고 판단되면 추가하자
public void setMember(Member member) {
this.member = member;
member.getOrders().add(this);
}
상황에 맞게 설계하자
결국 화면에 종속적으로 변하고 유지보수하기 어려워진다. 따라서 화면을 위한 로직을 처리하려면 DTO를 쓰자. DTO에 글자수 제한 같은 제약을 걸고 엔티티는 순수하게 유지하자.
영속성 컨텍스트가 더이상 관리하지 않는 엔티티
수정시 객체는 이미 DB에 한번 저장되어서 식별자가 존재한다. 이렇게 임의로 만들어낸 엔티티도 기존 식별자를 가지고 있으면 준영속 엔티티로 볼 수 없다
준영속 엔티티는 영속성 컨텍스트의 지원을 받을 수 없고 데이터를 수정해도 변경 감지 기능은 동작하지 않는다.
준영속 엔티티를 수정하는 방법은 변경 감지 기능과 병합 기능이 있다. 병합 사용시 모든 속성이 변경되며 변경 값이 없으면 null로 업데이트 될 위험이 있다.
영속성 컨텍스트에서 엔티티를 다시 조회한 후에 데이터를 수정하는 방법
트랜잭션 안에서 엔티티를 다시 조회, 변경값 선택 -> 트랜잭션 커밋 시점에 변경 감지가 동작해서 DB에 UPDATE SQL 실행
변경 감지 기능을 사용하려면 컨트롤러에서 엔티티를 생성하지 말자.
인수로 전달 받는 객체는 준영속 상태가 되어 수정하기 더 복잡해진다.
트랜잭션이 있는 서비스 계층에 식별자와 변경할 데이터를 전달하자.
서비스 계층에서는 엔티티를 조회하고 데이터를 직접 변경하자.
출처 : 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발