이 글은 인프런의 김영한 강사님 자바 ORM 표준 JPA 프로그래밍-기본 편 강의 내용을 바탕으로 작성되었습니다.
프록시란?
프록시 객체란 실제 객체가 아닌, 실제 클래스를 상속받아서 겉모양이 같게 만들어진 객체 (임시 객체라고 생각하면 편함) 하지만 프록시 객체를 호출하면 실제 객체의 메소드에서 호출이 됨
프록시 객체는 실제 객체에서 호출이 되었을때 초기화가 됨
LAZY를 사용해서 프록시로 조회가 가능하다
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch = FetchType.LAZY) //** @JoinColumn(name = "TEAM_ID")
private Team team;
}
예를들어
Member member = em.find(Member.class, 1L);
이 명령어로 사용자를 조회를 하면 일단 프록시로 Team에 대한 엔티티 정의(?)만 들고 있음, 그 이후에
Team team = member.getTeam();
이 명령어로 실제 DB에서 데이터를 조회하고 프록시는 초기화 됨
하지만 Member와 Team이 항상 같이 조회가 된다면
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch = FetchType.EAGER) //** @JoinColumn(name = "TEAM_ID")
private Team team;
}
이런식으로 @ManyToOne(fetch = FetchType.EAGER) 설정해주면됨. 이렇게 되면 SQL에서 한번에 함께 조회가 됨
주의 사항
- 가급적 실무에서는 EAGER 사용 금지
- @ManyToOne, @OneToOne은 기본이 EAGER이기 때문에 LAZY로 변경해줘야 됨
CASCADE란?
부모 엔티티를 저장할때 자식 엔티티도 함께 저장됨
@OneToMany(mappedBy="parent", cascade=CascadeType.ALL) -> 이런식으로 하면 자식 엔티티도 모두 함께 저장됨
고아 객체
고아 객체 제거: 부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제됨
@Entity
public class Parent {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent",cascade = CascadeType.REMOVE,orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
public void addChild(Child child){
childList.add(child);
child.setParent(this);
}
}
이런식으로 엔티티를 만든 후에
Parent findParent = em.find(Parent.class, parent.getId());
findParent.getChildList().remove(0);
tx.commit();
이런식으로 리스트에서 지워 준다면 지워진 자식테이블에서 해당 데이터가 삭제가 됨
예제
- 모든 연관관계를 지연 로딩으로 설정
- @ManyToOne, @OneToOne은 기본이 즉시 로딩이므로 지연 로딩으로 변경
연관관계 지연로딩 변경
@Entity
public class Category extends BaseEntity{
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PARENT_ID")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
@ManyToMany
@JoinTable(name = "CATEGORY_ITEM",
joinColumns = @JoinColumn(name = "GATEGORY_ID"),
inverseJoinColumns = @JoinColumn(name = "ITEM_ID"))
private List<Item> items = new ArrayList<>();
}
- Order -> Delivery를 영속성 전이 ALL 설정
- Order -> OrderItem을 영속성 전이 ALL 설정
@Entity
@Table(name = "ORDERS")
public class Order extends BaseEntity{
@Id
@GeneratedValue
@Column(name = "ORDER_ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="MEMBER_ID")
private Member member;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "DELIVERY_ID")
private Delivery delivery;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
}
'spring > JPA' 카테고리의 다른 글
[JPA] 객체지향 쿼리 언어(JPQL) (0) | 2023.12.14 |
---|---|
[JPA] 값타입 (0) | 2023.12.12 |
[JPA] 고급매핑 (0) | 2023.12.11 |
[JPA] 다양한 연관관계 매핑 (0) | 2023.12.08 |
[JPA] 연관관계 매핑 기초 (2) | 2023.12.07 |