JPA를 공부하던 중 엔티티를 설계할 때 주의해야 할 점을 정리해보려고 합니다.
- 엔티티 설계시 가급적이면 Setter를 사용하지 말자!
Setter가 모두 열려있으면, 변경점을 찾기 어렵고, 열어놓고 누군가 사용한다면 그 해당 로직을 쭉 읊으면서 변경점을 찾아야 한다는 번거로움이 있습니다. 또한, 리팩터링 하기가 다소 어렵습니다.
- 모든 연관관계는 지연 로딩으로 설정하자!(제일 중요!)
연관관계는 즉시 로딩과 지연 로딩이 있습니다. 즉시 로딩은 연관된 테이블을 로딩하는 시점에 모두 로딩해주는 방식입니다. 이 방식은 비추! 사용하면 안됩니다. 즉시로딩( EAGER )은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어렵습니다. 특히 JPQL을 실행할 때 N+1 문제가 자주 발생합니다. 실무에서 모든 연관관계는 지연로딩( LAZY )으로 설정해야 합니다. 연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용한다. @XToOne(OneToOne, ManyToOne) 관계는 기본이 즉시로딩이므로 직접 지연로딩으로 설정해야 합니다.
@ManyToOne(fetch = FetchType.LAZY)
@OneToOne(fetch = FetchType.LAZY)
- 컬렉션은 필드에서 초기화하자!
컬렉션은 필드에서 바로 초기화하는 게 안전합니다. 또한, null 문제에서 안전합니다. 하이버네이트는 엔티티를 영속화할 때, 컬랙션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경합니다. 만약 getOrders()처럼 임의의 메서드에서 컬력션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있습니다. 따라서 필드 레벨에서 생성하는 것이 가장 안전하고, 코드도 간결합니다.
Member member = new Member();
System.out.println(member.getOrders().getClass());
em.persist(team);
System.out.println(member.getOrders().getClass());
//출력 결과
class java.util.ArrayList
class org.hibernate.collection.internal.PersistentBag
하이버네이트가 관리하는 컬랙션으로 함부로 바꾸면 안 됩니다.
- 테이블, 컬럼명 생성전략
1. 논리명 생성: 명시적으로 컬럼, 테이블명을 직접 적지 않으면 ImplicitNamingStrategy 사용 spring.jpa.hibernate.naming.implicit-strategy : 테이블이나, 컬럼명을 명시하지 않을 때 논리명 적용
2. 물리명 적용:
spring.jpa.hibernate.naming.physical-strategy : 모든 논리명에 적용됨, 실제 테이블에 적용 (username usernm 등으로 회사 룰로 바꿀 수 있음)
'혼자 공부하는 것들 > JPA' 카테고리의 다른 글
[지구최강 JPA 스터디] 6-7주차 연관관계 매핑 4가지와 단방향, 양방향! (0) | 2022.08.14 |
---|---|
[지구최강 JPA 스터디] 4-5주차 객체 설계 할때는 단방향으로!? (0) | 2022.07.28 |
[지구최강 JPA 스터디] 2-3주차 몰아서 정리하자! (1) | 2022.07.13 |
[지구최강 JPA 스터디] 1주차 영속성 컨텍스트란? (0) | 2022.06.30 |
내가보려고 정리한 JPA OSIV(Open EntityManager In View) (0) | 2022.06.22 |
댓글