본문 바로가기

[JPA] 도메인 분석 설계

@cayman0312025. 12. 2. 11:41

웹 애플리케이션을 개발 할때 엔티티 설계시 주의해야 할 점에 대해 알아볼 것이다.

엔티티 설계시 주의점

외래 키가 있는 곳을 연관관계의 주인으로 정하기

연관관계의 주인은 단순히 외래키를 누가 관리하느냐의 문제이지 비즈니스상 우위에 있다고 주인으로 정하면 안된다.

예를 들어, 자동차와 바퀴가 있을 때 일대다 관계에서 항상 다쪽에 외래키가 존재하므로 외래 키가 있는 바퀴를 연관관계의 주인으로 하는것이 좋다.

자동차를 연관관계의 주인으로 정하면 자동차가 관리하지 않는 바퀴 테이블의 외래 키 값이 업데이트 되므로 관리와 유지보수가 어렵고 추가적인 별도의 업데이트 쿼리가 발생하는 성능 문제도 존재한다.

@ManyToMany를 사용하지 말자

중간 테이블에 컬럼을 추가할 수 없고, 세밀하게 쿼리를 실행하기 어렵기 때문에 실무에서 사용하기에 한계가 존재한다.

중간 엔티티를 만들고 @ManyToOne, @OneToMany로 매핑하여 사용하듯이 다대다 매핑을 일대다 다대일 매핑으로 풀어내어 사용하는 것이 좋다.

엔티티에는 가급적 Setter를 사용하지 말자

@Setter은 모든 변경에 열려있다. 따라서 변경 포인트가 많아지고 관리와 유지보수가 어려워진다.

따라서 이를 제거하고 생성자에서 값을 모두 초기화하여 변경 불가능하게 설계하는것이 좋다.

모든 연관관계는 지연로딩으로 설정하자

즉시로딩(EAGER)은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어렵다. 특히 N+1이 자주 발생할 수 있다.

따라서 우리는 모든 연관관계는 지연로딩(LAZY)로 설정해야 한다.

특히 @XToOne관계는 기본이 즉시로딩이므로 직접 지연로딩으로 설정하여 사용하자.

컬렉션은 필드에서 초기화 하자.

컬렉션은 필드에서 바로 초기화하는것이 안전하다. 이를 사용하면 얻는 장점은 다음과 같다.

  • null문제에서 안전하다.
  • 하이버네이트는 엔티티를 영속화할 때, 컬렉션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다. 임의의 메서드에서 컬렉션을 잘못 생성하면 하이버네이트 내부에서 문제가 발생할 수 있다.
  • 따라서 필드레벨에서 생성하는 것이 안전하고 간결하다.
Member member = new Member();
System.out.println(member.getOrders().getClass());
em.persist(member);
System.out.println(member.getOrders().getClass());
//출력 결과
class java.util.ArrayList
class org.hibernate.collection.internal.PersistentBag

테이블, 컬럼명 생성 전략

  1. 카멜 케이스 -> 언더스코어(memberMap -> member_map)
  2. .(점) -> 언더스코어
  3. 대문자 -> 소문자

기본적으로 스프링 부트가 설정하는 규약을 따르나 직접 변경이 가능하다.

  1. 논리명 생성: 명시적으로 컬럼, 테이블을 직접 적지 않으면 ImplicitNamingStrategy를 사용한다.
    • spring.jpa.hibernate.naming.implicit-strategy
    • 테이블이나 컬럼명을 명시하지 않을 때 논리명을 적용한다.
  2. 물리명 적용
    • spring.jpa.hibernate.naming.physical-strategy
    • 모든 논리명에 적용된다. 실제 테이블에 적용된다.

'Develop > Spring' 카테고리의 다른 글

[JPA] 회원 도메인  (0) 2025.12.02
[JPA] 변경 감지와 병합(merge)  (0) 2025.12.02
[MVC] 요청 매핑  (0) 2025.12.02
[MVC] 핸들러 매핑과 핸들러 어댑터  (0) 2025.12.02
[MVC] http 응답  (0) 2025.12.02
cayman031
@cayman031 :: 그누로그

목차