[JPA] 영속성 컨텍스트, 연관관계

호호빵·2022년 9월 13일
0

JPA

목록 보기
5/8

0. Spring Data JPA를 사용하지 않았다면

  • Entity Manager 를 사용해야 함
// Entity를 생성!
Member minsook = new Member();
member.setId("abcd1234"); 
member.setUsername("민숙");

// EntityManager를 생성해줄 EntityManagerFactory를 만들어야합니다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa심화주차");

// Entity를 관리해줄 EntityManager를 EntityManagerFactory에서 생성!
EntityManager em = emf.createEntityManager();

// 엔티티를 영속화(저장)
em.persist(minsook);
// 엔티티를 찾기
em.find(Member.class, 100L);


1. 영속성 컨텍스트

  • Entity 를 영구 저장 하는 환경 이라는 뜻
  • 어플리케이션이 DB에서 꺼내온 데이터 객체를 보관하는 가상의 DB 같은 역할
  • Entity Manager 를 통해 엔티티를 조회하거나 저장할때 엔티티를 보관 및 관리

+ 추가

  • 서비스별로 하나의 EntityManager Factory가 존재하며 Entity Manager Factory에서 디비에 접근하는 트랜잭션이 생길 때 마다 쓰레드 별로 EntityManager를 생성하여 영속성 컨텍스트에 접근한다!!
  • 영속성 컨텍스트는 EntityManager를 생성할 때 만들어지며 EntityManager를 통해 영속성 컨텍스트에 접근하고 관리한다.
  • 다음 코드로 Entity를 영속성 컨텍스트에 저장할 수 있다.
    -> entityManager.persist(entity);
  • Spring에서는 EntityManager를 주입하여 사용하면 같은 트렌잭션의 범위에 있는 EntityManager는 같은 영속성 컨텍스트에 접근한다.

Entity의 상태

1. 비영속(new/transient)

  • 영속성 컨텍스트와 전혀 관계과 없는 상태
  • 엔티티 객체를 생성하였지만 아직 영속성 컨텍스트에 저장하지 않은 상태를 의미

2. 영속(managed)

  • 영속성 컨텍스트에 저장된 상태, 엔티티가 영속성 컨텍스트에 의해 관리됨
  • 영속 상태가 되었다고 바로 DB에 값이 저장되지 않고, 트랜젝션의 커밋시점에 영속성 컨텍스트에 있는 정보들을 DB에 쿼리로 날림

3. 준영속(detached)

  • 영속성 컨텍스트에 저장이되었다가 분리된 상태
  • 엔티티를 준영속 상태로 만드려면 entityManager.detach() 호출
  • 특징
    • 1차캐시, 쓰기 지연, 변경 감지, 지연 로딩을 포함한 영속성 컨텍스트가 제공하는 어떠한 기능도 동작하지 않음
    • 식별자 값을 가짐

4. 삭제(removed)

  • 영속성 컨텍스트와 DB에서 해당 엔티티를 삭제하여 삭제된 상태
// 1. 비영속, 엔티티를 생성
Member minsook = new Member();

// 2. 영속, 엔티티 매니저를 통해 영속성 컨텍스트에 엔티티를 저장
// 클래스내에 Autowired로 EntityManager 추가
@Autowired
private EntityManager em;

    Member minsook = new Member();  // 객체만 생성한 비영속 상태
    
    em.persist(minsook);            // 객체를 저장한 영속상태


// 3. 준영속, 엔티티를 영속성 컨택스트에서 분리해 준영속 상태 만들기
em.detach(minsook);
// 영속성 컨텍스트를 비우면 엔티티들은 준영속 상태가 됨
em.clear();
// 영속성 컨택스트를 종료해도 엔티티들은 준영속 상태가 됨
em.close();

// 준영속 -> 영속, 엔티티를 merge하면 다시 영속 상태가 됨
em.merge(minsook);


// 4. 삭제, 엔티티를 영속성 컨텍스트와 DB에서 삭제
em.remove(minsook)


장점

  • 1차캐시
  • 동일성 보장(Identity)
  • 트랙잭션을 지원하는 쓰기 지연 (Transactional write-behind)
  • 변경 감지 (Dirty Checking)
  • 지연 로딩 (Lazy Loading)

2. 연관관계 Mapping

단방향 연관관계

@ManyToOne (N: 1)

  • 주요 속성으로는 optional, fetch, cascade
  • optional : false로 설정하면 항상 연관된 엔티티가 있어야 생성할 수 있다는 뜻

@JoinColumn(name="food_id")

  • 외래키를 매핑할 때 사용

양방향 연관관계

  • Member, Orders, Food
@Getter
@Entity
@NoArgsConstructor
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
	@Column(nullable = false)
    private String memberName;

    @OneToMany(mappedBy = "member", fetch = FetchType.EAGER)
    private List<Orders> orders = new ArrayList<>();

    public Member(String memberName) {
        this.memberName = memberName;
    }
}
@Getter
@Entity
@NoArgsConstructor
public class Orders {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "food_id")
    private Food food;     // 한 음식은 여러 주문에 포함 가능 

    @ManyToOne
    @JoinColumn(name = "member_id")
    private Member member;  // 한 멤버는 여러 주문 가능+

    public Orders(Food food, Member member) {
        this.food = food;
        this.member = member;
    }
}
@Getter
@Entity
@NoArgsConstructor
public class Food {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false)
    private String foodName;
    @Column(nullable = false)
    private int price;

    @OneToMany(mappedBy = "food",fetch = FetchType.EAGER)
    private List<Orders> orders = new ArrayList<>();

    public Food(String foodName, int price) {
        this.foodName = foodName;
        this.price = price;
    }
}
  • 멤버 한명은 여러 주문 가능, 한 음식은 여러 주문에 포함 가능
     Member   				Orders    				Food
        1 			:      	  N
							  N 		   : 		  1
                              
@OneToMany - orders  @ ManyToOne - member
					 @ ManyToOne - food      @ OneToMany - orders
                    

@OneToMany

  • One이 연관관계의 주인 (mappedBy로 표현)
  • 연관관계의 주인만이 DB 연관관계와 매핑되고 외래키를 관리하게 되어있음

추가적으로 알아볼 것

  • 영속성 컨텍스트는 왜 이렇게 만들어졌을까?
    • 1차 캐시
    • 쓰기 지연 SQL
    • DirtyChecking
    • 데이터 어플리케이션 단의 동일성 보장
    • flush
  • Proxy 객체
  • cascade

영속성 컨텍스트
스파르타코딩클럽 - Spring 숙련
https://velog.io/@neptunes032/JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80

profile
하루에 한 개념씩

0개의 댓글