스프링데이터 + JPA/웹 애플리케이션 개발

9. 엔티티 개발 주의점

sdafdq 2023. 11. 5. 17:56

가급적 setter 사용 금지

아니면 private 해서 비즈니스 메소드를 따로 만들어서 하셈

 

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

이게 JPA가 자동으로 쿼리 만들어서 나가는 거기 때문에 어떤 쿼리들이 나갈 지 연관관계는 예측이 잘 안될수도 있음. 근데 즉시로딩으로 하면 다 끌고 오기 때문에 성능적 손해가..

그냥 다 지연로딩으로 하셈.

@XToOne은 다 즉시로딩이 기본이라 직접 지연로딩으로 설정 해야 함 (ctrl + shift + F가 모든 파일에서 단어찾기)

 

한방에 같이 가져오고 싶으면 fetch join을 사용하셈.

 

컬렉션은 new ArrayList<>()로 초기화 해놔라.

null 에러에서 안전함.

거기다 하이버네이트에서 영속화 할때 컬렉션은 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변강 함.

그래서 그냥 원초적으로 필드레벨에서 생성해 놓는 것이 안전함. 어딘가에서 컬렉션을 잘못 생성할 수 있고..

저렇게 초기화 해 놓은 다음 getClass() 해 보면 ArrayList로 나오는 데, 영속화 등록 이후는 org.hibernate.collection.internal.PersistentBag 요걸로 나옴.

영속성관리를 위해 하이버네이트가 제공하는 컬렉션으로 바뀌므로, 다른 컬렉션으로 바꿀 생각말고, 그냥 저걸로 쓰셈.

 

테이블, 컬럼명 생성전략

스프링 부트에서 하이버네이트는 기본 매핑 전략이 있음. (CamelCaseToUnderscoresNamingStrategy)

하이버 네이트 기본은 필드명 그대로 테이블 명으로 사용이고,

스프링 부트에서의 신규 기본 설정은

카멜케이스 -> 언더스코어

점 -> 언더스코어

대문자 -> 소문자

 

만약 회사마다 표준 있다면 저거 상속받아서 구현후 등록하면 될 듯.

ImplicitNamingStrategy 이거는 논리명, 그러니까 테이블명이나 컬럼명을 직접 적지 않았을 때 적용하는 것

PhysicalNamingStrategy 이거는 물리명. 테이블명이나 컬럼명 직접 명시해줬을 때

username -> xx_username 이런식으로 되게끔 가능함.

저것들로 매핑전략 바꿀 수 있음.

 

cascade

폭포, 라는 뜻도 있는 영속성 전파하는 옵션이다.

그러니까, 

@Entity
Order{
    @OneToMany(mappedBy = "order")
    private List<OrderItem> orderItems = new ArrayList<>();
}

 

이렇게 하면 원래,

persist(orderItemA);
persist(orderItemB);
persist(orderItemC);
order.addItem(orderItemA);
order.addItem(orderItemB);
order.addItem(orderItemC);
persist(order)

 

이런 식으로 해야 하는데,

@Entity
Order{
    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
    private List<OrderItem> orderItems = new ArrayList<>();
}

하면

order.addItem(orderItemA);
order.addItem(orderItemB);
order.addItem(orderItemC);
persist(order)

이렇게만 해도 된다.

말 그대로 영속성 전파다. 부모? 라기보다 자기를 가지고 있는 클래스의 영속성 동작에 영향을 받는 것이다.

CascadeType은 

ALL : 모두적용

PERSIST : 영속

REMOVE : 삭제

MERGE : 병합

REFRESH : REFRESH

DETACH : DETACH

이렇게 6가지 있는데,

ALL, PERSIST만 쓴다.

짝 같은 거나 완전히 종속적인 거에 쓸 때 좋다.

 

양방관계 편의 메소드

그냥 연관관계의 하인 쪽은 주인으로부터 값을 읽어오는거지, 하인쪽은 바꿔봤자 DB에 반영도 안되고, 연관관계가 있는 객체에도 반영이 안된다.

그럼 둘 중 하나 양방관계 편의 메소드를 내가 정의하면 된다.

예를들어

@Entity(name = "orders")
public class Order {
    public void changeMember(Member member){
        this.member = member;
        member.getOrders().add(this);
    }
}

이렇게.

주로 호출을 많이 하는 쪽에 정의해 주는 게 좋음.

 

 

'스프링데이터 + JPA > 웹 애플리케이션 개발' 카테고리의 다른 글

11. 애플리케이션 아키텍처  (0) 2023.11.05
10. 구현 요구사항  (0) 2023.11.05
8. 엔티티 개발 2  (0) 2023.11.05
7. 엔티티 개발  (0) 2023.11.05
6. 도메인 모델과 테이블 설계  (0) 2023.11.04