ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA - Entity 설계시 주의점
    Spring/JPA 2022. 3. 16. 19:18
    728x90
    반응형

     

     

    Entity 설계 시 주의점

     

     Entity 설계 시 다음과 같은 사항들을 주의해야한다.

     

     

    엔티티에는 가급적 Seter를 사용 금지

     

     Setter를 무분별하게 사용하게 되면 어디서 해당 값이 변경되었는지 추적하기가 힘들어진다. 즉, 유지보수가 어려워지기 때문에 사용하지 않는 것이 좋다. Setter가 필요할 경우에는 추적하기 쉽도록 메서드를 따로 생성해준다.

     

     

    @Entity
    @Getter
    public abstract class Item {
    
        @Id
        @GeneratedValue
        @Column(name = "item_id")
        private Long id;
    
        private String name;
        private int price;
        private int stockQuantity;
    
        // Setter 대신 생성해준 메서드
        public void addStock(int quantity) {
            this.stockQuantity += quantity;
        }
    
        // Setter 대신 생성해준 메서드
        public void removeStrock(int quantity) {
            int restStock = this.stockQuantity - quantity;
            if (restStock < 0) {
                throw new NotEnoughStockException("need more stock");
            }
            this.stockQuantity = restStock;
        }
    }

     

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

     

     즉시로딩은 어떤 SQL이 실행될지 예측하기 어렵고, JPQL을 실행할 때 N+1 문제가 자주 발생하게 된다. 따라서 실무에서 Entity 설계 시 연관관계는 지연로딩(LAZY)으로 설정해야 한다. 만약 지연로딩 설정하였을 때 주 엔티티가 연관된 엔티티(참조 객체)의 정보도 함께 DB에서 조회해야 한다면 fetch join 또는 엔티티 그래프 기능을 사용하면 된다.

     

     

    @XtoOne(OneToOne, ManyToOne) 관계는 기본이 즉시로딩이므로 꼭! 지연로딩으로 설정!

     


     

    컬렉션은 필드에서 초기화

     

     컬렉션은 다음과 같이 2가지 문제가 있으므로 필드에서 바로 초기화하는 것이 안전하다.

     

    1. NPE 문제에서 안전

     

    2. 하이버네이트는 엔티티를 영속화할 때, 컬렉션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다. 만약 getOrders()처럼 임의의 메서드에서 컬렉션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있다. 따라서 필드 레벨에서 생성하는 것이 가장 안전하고 코드도 간결해진다.

     

    @Entity
    @Getter
    public class Member {
    
        @Id
        @GeneratedValue
        @Column(name = "member_id")
        private Long id;
    
        @NotEmpty
        private String name;
    
        @Embedded
        private Address address;
    
        @JsonIgnore
        @OneToMany(mappedBy = "member")
        private List<Order> orders = new ArrayList<>(); // 필드에서 초기화
    
    
    }

     

     

     

    728x90
    반응형

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

    JPA - API 개발 고급(OneToOne, ManyToOne 지연 로딩과 조회 성능 최적화)  (0) 2022.03.22
    JPA - API 기본  (0) 2022.03.21
    JPA - 설계 순서  (0) 2022.03.16
    JPA - JPQL 기본 문법 2  (0) 2022.03.11
    JPA - JPQL 기본 문법과 기능  (0) 2022.03.11

    댓글

Designed by Tistory.