JPA

JPA ํ•™์Šต๋ชฉ๋ก

devJK93 2024. 12. 21.

๐Ÿ“ GPT์—๊ฒŒ ๋ฌผ์–ด๋ณธ ์งˆ๋ฌธ ๋ชฉ๋ก

 

1) ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ (1:N vs N:1)

JPA ์—์„œ N๋Œ€1์€ ํ…Œ์ด๋ธ”์—์„œ ์ž์‹ํ…Œ์ด๋ธ”์— FK๊ฐ€ ์žˆ๋“ฏ์ด ๊ฐ์ฒด๊ด€์— ๊ด€๊ณ„์—์„œ๋„ N ์ชฝ์ด ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์„ ๊ฐ€์ ธ๊ฐ€์ž–์•„
๋ฐ˜๋ฉด์— 1๋Œ€N์€ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์„ 1์ชฝ์ด ๊ฐ€์ ธ๊ฐ€์ž–์•„ (ex. TEAM, MEMBER)
๊ตณ์ด ์ด๋ ‡๊ฒŒ ํ•˜๋Š” ์ด์œ ๊ฐ€ ์žˆ์„๊นŒ?

@OneToMany 
@JoinColumn(name="TEAM_ID") 
List<MEMBER> members = new ArrayList<>();

2) mappedBy ๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

JPA ๊ฐ์ฒด๊ฐ„์˜ ์–‘๋ฐฉํ–ฅ ์ฒ˜๋ฆฌ๋ฅผ ํ• ๋•Œ (๊ฐ์ฒด : MEMBER, TEAM)

@OneToMany(mappedBy="team")

 

์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์ž–์•„ ์™œ ํ•ด์ฃผ๋Š”๊ฑฐ์ง€?

์•ˆํ•ด์ฃผ๋ฉด ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ญ์•ผ?

์–ด์ฐจํ”ผ ์—ฐ๊ด€๊ด€๊ณ„ ๋ฉ”์„œ๋“œ๋กœ ๋™๊ธฐํ™”์ฒ˜๋ฆฌ ํ•ด์ฃผ์ž–์•„.

/* ์—ฐ๊ด€๊ด€๊ณ„ ๋ฉ”์„œ๋“œ */ 
private void addTeam(Team team) { 
	this.team = team; team.getMembers().add(this); 
}

 

๐Ÿ“ ๋‹ต๋ณ€ ์š”์•ฝ

  1. `mappedBy`๋ฅผ ์•ˆํ•ด์ฃผ๋ฉด JPA๋Š” ์–‘์ชฝ ๋ชจ๋‘๋ฅผ ์—ฐ๊ด€๊ด€๊ณ„์˜ ์ฃผ์ธ์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿด๊ฒฝ์šฐ ์–‘์ชฝ์—์„œ FK๋ฅผ ๊ด€๋ฆฌํ•˜๋ ค ํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์กฐ์ธํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค.
  3. ํ”„๋ก์‹œ ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ด๋‚˜ Lazy Loading ์„ค์ •์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

3) ์ง€์—ฐ๋กœ๋”ฉ vs ์ฆ‰์‹œ๋กœ๋”ฉ

JPA์—์„œ ์ง€์—ฐ๋กœ๋”ฉ๊ณผ ์ฆ‰์‹œ๋กœ๋”ฉ์€ ์–ด๋–ค ๊ฐœ๋…์ผ๊นŒ?

N+1 ๋ฌธ์ œ์™€๋„ ๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ๋“ค์—ˆ๋‹ค.


4) ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ 1๋Œ€1 ๊ด€๊ณ„์—์„œ  ์ฃผํ…Œ์ด๋ธ”๊ณผ ๋Œ€์ƒํ…Œ์ด๋ธ” ์ค‘ ์™ธ๋ž˜ํ‚ค ์„ ์ •

1๋Œ€1๊ด€๊ณ„์—์„œ ์ฃผํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ๊ฒƒ๊ณผ ๋Œ€์ƒํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ๋Š” ๊ฒƒ์˜ ์žฅ๋‹จ์ ์€?

(ex. ์ฃผํ…Œ์ด๋ธ” : MEMBER, ๋Œ€์ƒํ…Œ์ด๋ธ” : LOCKER)

 

๋Œ€์ƒํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ์œผ๋ฉด ๋‚˜์ค‘์— MEMBER : LOCKER ๋ฅผ 1๋Œ€N ๊ด€๊ณ„๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์„ ๋•Œ LOCKER์˜ FK ์ œ์•ฝ์กฐ๊ฑด์—์„œ UNIQUE๋งŒ ๋นผ๋ฉด๋˜๋‹ˆ๊น ์„ค๊ณ„๋œ ํ…Œ์ด๋ธ”์„ ๋งŽ์ด ๊ณ ์น  ํ•„์š”๊ฐ€ ์—†์–ด์„œ ์ข‹์€๊ฑด ์•Œ๊ฒ ์–ด ๋‹จ์ ์€ ํ”„๋ก์‹œ ๊ธฐ๋Šฅ์˜ ํ•œ๊ณ„๋กœ ์ง€์—ฐ๋กœ๋”ฉ์œผ๋กœ ์„ค์ •ํ•ด๋„ ํ•ญ์ƒ ์ฆ‰์‹œ๋กœ๋”ฉ ๋œ๋‹ค๋Š”๋ฐ ๋ฌด์Šจ๋ง์ด์ง€? ๊ทธ ์™ธ์˜ ์žฅ์ ์ด๋‚˜ ๋‹จ์ ์ด ์žˆ์„๊นŒ?

 

์ฃผํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ํ‚ค๊ฐ€ ์žˆ์œผ๋ฉด ์žฅ์  : ์ฃผ ํ…Œ์ด๋ธ”๋งŒ ์กฐํšŒํ•ด๋„ ๋Œ€์ƒ ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ ๊ฐ€๋Šฅ ๋‹จ์  : ๊ฐ’์ด ์—†์œผ๋ฉด ์™ธ๋ž˜ํ‚ค์— NULL ํ—ˆ์šฉ ์ด๊ฑฐ ๋งž๋‚˜? ๊ฐ์ฒด์ง€ํ–ฅ ๊ฐœ๋ฐœ์ž๊ฐ€ ์„ ํ˜ธํ•˜๊ณ  JPA๋งคํ•‘์ด ํŽธ๋ฆฌํ•˜๋‹ค๊ณ  ํ•˜๋Š”๋ฐ ์™œ ๊ทธ๋Ÿฐ๊ฑฐ์ง€?


5) ๊ณ„์ธต๊ตฌ์กฐ์˜ ํ…Œ์ด๋ธ” JPA ์—”ํ‹ฐํ‹ฐ ์„ค๊ณ„

package jpashop.jpaorder.domain;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Category {

  @Id @GeneratedValue
  private Long id;

  private String name;

  @ManyToMany
  private List<Item> items = new ArrayList<>();

  @ManyToOne
  @JoinColumn(name = "PARENT_ID")
  private Category parent;

  @OneToMany(mappedBy = "parent")
  private List<Category> child = new ArrayList<>();
}

 

์ž์‹ ์„ ์ฐธ์กฐํ•˜๋Š” ๊ณ„์ธต๊ตฌ์กฐ๋Š” @Entity๊ฐ€ ์ด๋ ‡๊ฒŒ ์„ค๊ณ„๋˜๋Š”๊ฒŒ ๋งž๋‚˜?


6) JPA ๊ตฌ๋™ (Persistence, EntityManagerFactory, EntityManager, EntityTransaction)

Persistence, EntityManagerFactory, EntityManager, EntityTransaction์˜ ๊ฐœ๋…๊ณผ JPA ๊ตฌ๋™ํ๋ฆ„์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ค˜

 

๐Ÿ“ ๋‹ต๋ณ€ ์š”์•ฝ

 

JPA ๊ตฌ๋™๋ฐฉ์‹

๐Ÿ“ JPA ๊ตฌ๋™ ๋ฐฉ์‹JPA์˜ ๊ตฌ๋™ ๋ฐฉ์‹์€ Persistence → EntityManagerFactory → EntityManager์˜ ๊ณ„์ธต์  ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ฃผ์š” ํด๋ž˜์Šค์™€ ๊ตฌ๋™ ๋ฐฉ์‹์„ ๋‹จ๊ณ„๋ณ„๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.1. JPA์˜ ์ฃผ์š” ํด๋ž˜์Šค ๋ฐ ์—ญํ• Persistence:JPA

dev-jk93.tistory.com

 


7) JPA PK ์ƒ์„ฑ์ „๋žต @GeneratedValue(strategy = GenerationType.โ“)

JPA์˜  PK ์ƒ์„ฑ์ „๋žต(@GeneratedValue(strategy = GenerationType.?))์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ค˜

 

๐Ÿ“ ๋‹ต๋ณ€ ์š”์•ฝ

 

JPA ๊ตฌ๋™๋ฐฉ์‹

๐Ÿ“ JPA ๊ตฌ๋™ ๋ฐฉ์‹JPA์˜ ๊ตฌ๋™ ๋ฐฉ์‹์€ Persistence → EntityManagerFactory → EntityManager์˜ ๊ณ„์ธต์  ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ฃผ์š” ํด๋ž˜์Šค์™€ ๊ตฌ๋™ ๋ฐฉ์‹์„ ๋‹จ๊ณ„๋ณ„๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.1. JPA์˜ ์ฃผ์š” ํด๋ž˜์Šค ๋ฐ ์—ญํ• Persistence:JPA

dev-jk93.tistory.com


8) Domain Model Pattern VS Transaction Script Pattern

1,2 ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด์„œ ๋„๋ฉ”์ธ ๋ชจ๋ธ ํŒจํ„ด vs ํŠธ๋žœ์žญ์…˜ ์Šคํฌ๋ฆฝํŠธ ํŒจํ„ด์„ ์„ค๋ช…ํ•ด์ค˜

// 1
@Entity
public class Order {

    @Id
    @GeneratedValue
    private Long id;

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

    @OneToOne(cascade = CascadeType.ALL)
    private Delivery delivery;

    private LocalDateTime orderDate;

    @Enumerated(EnumType.STRING)
    private OrderStatus status; // ์˜ˆ: ORDERED, CANCELED

    //== ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ==//

    // ์ฃผ๋ฌธ ์ƒ์„ฑ
    public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems) {
        Order order = new Order();
        order.setMember(member);
        order.setDelivery(delivery);
        for (OrderItem orderItem : orderItems) {
            order.addOrderItem(orderItem);
        }
        order.setOrderDate(LocalDateTime.now());
        order.setStatus(OrderStatus.ORDERED);
        return order;
    }

    // ์ฃผ๋ฌธ ์ทจ์†Œ
    public void cancel() {
        if (delivery.getStatus() == DeliveryStatus.COMPLETE) {
            throw new IllegalStateException("์ด๋ฏธ ๋ฐฐ์†ก ์™„๋ฃŒ๋œ ์ฃผ๋ฌธ์€ ์ทจ์†Œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
        }
        this.setStatus(OrderStatus.CANCELED);
        for (OrderItem orderItem : orderItems) {
            orderItem.cancel(); // ์ฃผ๋ฌธ์ƒํ’ˆ๋„ ์ทจ์†Œ
        }
    }

    // ์ด ์ฃผ๋ฌธ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ
    public int getTotalPrice() {
        return orderItems.stream()
                .mapToInt(OrderItem::getTotalPrice)
                .sum();
    }
}
// 2
@Entity
public class Order {

    @Id
    @GeneratedValue
    private Long id;

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

    @OneToOne(cascade = CascadeType.ALL)
    private Delivery delivery;

    private LocalDateTime orderDate;

    @Enumerated(EnumType.STRING)
    private OrderStatus status; // ์˜ˆ: ORDERED, CANCELED

    // Getter, Setter๋งŒ ์กด์žฌ
    public void addOrderItem(OrderItem orderItem) {
        this.orderItems.add(orderItem);
        orderItem.setOrder(this);
    }
}

@Service
@Transactional
public class OrderService {

    private final OrderRepository orderRepository;
    private final MemberRepository memberRepository;

    public OrderService(OrderRepository orderRepository, MemberRepository memberRepository) {
        this.orderRepository = orderRepository;
        this.memberRepository = memberRepository;
    }

    // ์ฃผ๋ฌธ ์ƒ์„ฑ
    public Long createOrder(Long memberId, Delivery delivery, List orderItems) {
        // ํšŒ์› ์กฐํšŒ
        Member member = memberRepository.findById(memberId)
                .orElseThrow(() -> new IllegalArgumentException("ํšŒ์›์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));

        // ์ฃผ๋ฌธ ์ƒ์„ฑ
        Order order = new Order();
        order.setMember(member);
        order.setDelivery(delivery);
        for (OrderItem orderItem : orderItems) {
            order.addOrderItem(orderItem);
        }
        order.setOrderDate(LocalDateTime.now());
        order.setStatus(OrderStatus.ORDERED);

        // ์ฃผ๋ฌธ ์ €์žฅ
        orderRepository.save(order);
        return order.getId();
    }

    // ์ฃผ๋ฌธ ์ทจ์†Œ
    public void cancelOrder(Long orderId) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new IllegalArgumentException("์ฃผ๋ฌธ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));

        if (order.getDelivery().getStatus() == DeliveryStatus.COMPLETE) {
            throw new IllegalStateException("์ด๋ฏธ ๋ฐฐ์†ก ์™„๋ฃŒ๋œ ์ฃผ๋ฌธ์€ ์ทจ์†Œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
        }

        // ์ƒํƒœ ๋ณ€๊ฒฝ
        order.setStatus(OrderStatus.CANCELED);

        // ์ฃผ๋ฌธ์ƒํ’ˆ ์ทจ์†Œ
        for (OrderItem orderItem : order.getOrderItems()) {
            orderItem.cancel(); // ์ฃผ๋ฌธ์ƒํ’ˆ ์ทจ์†Œ ๋กœ์ง ํ˜ธ์ถœ
        }
    }

    // ์ด ์ฃผ๋ฌธ ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ
    public int getTotalPrice(Long orderId) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new IllegalArgumentException("์ฃผ๋ฌธ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));
        return order.getOrderItems().stream()
                .mapToInt(OrderItem::getTotalPrice)
                .sum();
    }
}


๐Ÿ“ ๋‹ต๋ณ€ ์š”์•ฝ

 

๋„๋ฉ”์ธ ๋ชจ๋ธ ํŒจํ„ด vs ํŠธ๋žœ์žญ์…˜ ์Šคํฌ๋ฆฝํŠธ ํŒจํ„ด

๐Ÿ”ฅ ๋„๋ฉ”์ธ ๋ชจ๋ธ ํŒจํ„ด์ด๋ž€?๋„๋ฉ”์ธ ๋ชจ๋ธ ํŒจํ„ด(Domain Model Pattern)์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋„๋ฉ”์ธ ๊ฐ์ฒด(์—”ํ‹ฐํ‹ฐ) ๋‚ด๋ถ€์— ํฌํ•จ์‹œํ‚ค๋Š” ์„ค๊ณ„ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™, ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ, ๋ฐ

dev-jk93.tistory.com


9) em.persist VS em.merge

JPA์—์„œ em.persist ์™€ em.merge์˜ ์ž‘๋™๋ฐฉ์‹์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ค˜

 

๐Ÿ“ ๋‹ต๋ณ€ ์š”์•ฝ

 

em.persist vs em.merge

package jpabook.jpashop.repository;import jakarta.persistence.EntityManager;import jpabook.jpashop.domain.item.Item;import lombok.RequiredArgsConstructor;import org.springframework.stereotype.Repository;import java.util.List;@Repository@RequiredArgsConstru

dev-jk93.tistory.com


10) JPA ์ƒ์†๊ด€๊ณ„ ์ „๋žต ์„ค์ • (@Inheritance(strategy = InheritanceType.โ“))

์ƒ์†๊ด€๊ณ„์˜ ๊ฒฝ์šฐ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š”

1. ์Šˆํผํƒ€์ž… & ์„œ๋ธŒํƒ€์ž… ํ…Œ์ด๋ธ”๋กœ ๋‚˜๋ˆ„๊ธฐ

2. ๋‹จ์ผ ํ…Œ์ด๋ธ”

3. ๊ฐ๊ฐ์˜ ํ…Œ์ด๋ธ”

3๊ฐ€์ง€ ํƒ€์ž…์œผ๋กœ ์„ค๊ณ„๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€?

 

JPA์—์„œ๋Š” @Inheritance(strategy = InheritanceType.?)๋กœ ์ „๋žต์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์•Œ๊ณ  ์žˆ๋Š”๋ฐ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ค˜

์•„๋ž˜ ์งˆ๋ฌธ๋„ ๋‹ต๋ณ€ํ•ด์ค˜.

1. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค๋ฅผ ์ถ”์ƒํด๋ž˜์Šค (abstract)๋กœ ํ•ด์•ผํ•˜๋Š” ์ด์œ )

2. JOIN์ „๋žต๊ณผ ๋‹จ์ผํ…Œ์ด๋ธ” ์ „๋žต์˜ ์žฅ๋‹จ์  (JOIN์€ ์ •๊ทœํ™”๋กœ ์ธํ•ด ์ €์žฅ๊ณต๊ฐ„ ํšจ์œจํ™”๊ฐ€ ์žˆ์ง€๋งŒ ์ฟผ๋ฆฌ ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง„๋‹ค๋˜์ง€)

3. 'TABLE_PER_CLASS' ์ „๋žต์„ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋˜๋Š” ์ด์œ 

4. 'SINGLE_TABLE' ์ „๋žต์˜ ๊ฒฝ์šฐ๋„ ๋ถ€๋ชจํด๋ž˜์Šค ๋‹จ๋…์œผ๋กœ ์ƒ์„ฑ๋  ์ผ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€๋ชจํด๋ž˜์Šค๋Š” ์ถ”์ƒํด๋ž˜์Šค (abstract)๋กœ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์€์ง€


11) em.flush(), em.clear() ์˜๋ฏธ

em.flush(), em.clear()์˜ ์˜๋ฏธ

 

๐Ÿ“ ๋‹ต๋ณ€ ์š”์•ฝ

em.flush() → ์˜์†์„ฑ ์ปจํ…Œ์ด๋„ˆ์— ์žˆ๋Š” ์ฟผ๋ฆฌ๋ฅผ DB์— ๋‚ ๋ฆผ.

em.clear() → ์˜์†์„ฑ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋‚ ๋ฆผ.


11) ์ƒ์†๊ด€๊ณ„ ์—”ํ‹ฐํ‹ฐ์˜ @DiscriminatorColumn, @DiscriminatorValue

JPA ์ƒ์†๊ด€๊ณ„ ์—”ํ‹ฐํ‹ฐ์—์„œ @DiscriminatorColumn, @DiscriminatorValue๋ž€?

ITEM, BOOK, MOVIE, ALBUM ์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด์„œ ์„ค๋ช…ํ•ด์ค˜


12) @MappedSuperClass

@MappedSuperClass๋ž€?
๊ฐ‘์ž๊ธฐ DBA๊ฐ€ ์‹œ์Šคํ…œ์ปฌ๋Ÿผ์„ ๋ชจ๋“  ํ…Œ์ด๋ธ”์— ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค๊ณ  ํ•˜๋ฉด?

 

๐Ÿ“ ๋‹ต๋ณ€ ์š”์•ฝ

DB๋Š” ์Šˆํผํƒ€์ž…&์„œ๋ธŒํƒ€์ž… ํ˜•ํƒœ๋กœ ์„ค๊ณ„๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ ๊ฐ์ฒด๋Š” ์ƒ์†ํ˜•ํƒœ๋กœ ์‚ฌ์šฉ?

* ํŠน์ง• : 

  1. ์ƒ์†๊ด€๊ณ„ ๋งคํ•‘ X
  2. ์—”ํ‹ฐํ‹ฐ X, ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘ X
  3. ๋ถ€๋ชจ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” ์ž์‹ ํด๋ž˜์Šค์— ๋งคํ•‘์ •๋ณด๋งŒ ์ œ๊ณต
  4. ์กฐํšŒ, ๊ฒ€์ƒ‰ ๋ถˆ๊ฐ€(em.find(BaseEntity) ๋ถˆ๊ฐ€)
  5. ์ง์ ‘ ์ƒ์„ฑํ•ด์„œ ์‚ฌ์šฉํ•  ์ผ์ด ์—†์œผ๋ฏ€๋กœ ์ถ”์ƒํด๋ž˜์Šค ๊ถŒ์žฅ
  6. ํ…Œ์ด๋ธ”๊ณผ ๊ด€๊ณ„์—†๊ณ , ๋‹จ์ˆœํžˆ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋งคํ•‘ ์ •๋ณด๋ฅผ ๋ชจ์œผ๋Š” ์—ญํ• 
  7. ์ฃผ๋กœ ๋“ฑ๋ก์ผ, ์ˆ˜์ •์ผ, ๋“ฑ๋ก์ž, ์ˆ˜์ •์ž์™€ ๊ฐ™์€ ์‹œ์Šคํ…œ์ปฌ๋Ÿผ, ์ฆ‰ ์ „์ฒด ์—”ํ‹ฐํ‹ฐ์—์„œ ๊ณตํ†ต์œผ๋กœ ์ ์šฉํ•˜๋Š” ์ •๋ณด๋ฅผ ๋ชจ์„ ๋•Œ ์‚ฌ์šฉ
  8. ์ฐธ๊ณ  : @Entityํด๋ž˜์Šค๋Š” ์—”ํ‹ฐํ‹ฐ๋‚˜ @MappedSuperclass๋กœ ์ง€์ •ํ•œ ํด๋ž˜์Šค๋งŒ ์ƒ์† ๊ฐ€๋Šฅ.

์ถœ์ฒ˜ : ๊น€์˜ํ•œ๋‹˜์˜ ์ž๋ฐ” ORM ํ‘œ์ค€ JPA ํ”„๋กœ๊ทธ๋ž˜๋ฐ - ๊ธฐ๋ณธํŽธ

 


13) @SequenceGenerator(์†์„ฑ), @GeneratedValue(generator = ?)

@Entity @SequenceGenerator(name = "member_seq_generator", sequenceName = "member_seq", initialValue = 1, allocationSize = 50)
public class Member {

  @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq_generator")
  private Long id;
  
 }

 

@SequenceGenerator(์†์„ฑ), @GeneratedValue(generator = ?) ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ค˜


14) Fetch ์ „๋žต(๊ธฐ๋ณธ๊ฐ’ EAGER / LAZY)

Member member = em.find(Member.class, 1L);๋ฅผ ํ•˜๋ฉด Member๋งŒ ์กฐํšŒ๋˜๋‚˜?
@ManyToOne TEAM๋„ ๊ฐ™์ด ์กฐํšŒ๋˜๋‚˜?

 

์œ„ ์งˆ๋ฌธ์€ em.find() vs em.getReference() ์™€ ๊ด€๋ จ์ด ์žˆ๋‚˜?


 

๋Œ“๊ธ€