728x90
반응형

[JPA] Spring Boot JPA 핵심 개념 - 영속성 컨텍스트와 엔티티 생명주기

 

[JPA] Spring Boot JPA 핵심 개념 - 영속성 컨텍스트와 엔티티 생명주기

[JPA] JPA란 무엇인가? Java Persistence API의 핵심 개념 정리 - 2 [JPA] JPA란 무엇인가? Java Persistence API의 핵심 개념 정리 - 2[JPA] JPA란 무엇인가? Java Persistence API의 핵심 개념 정리 [JPA] JPA란 무엇인가? Java P

crushed-taro.tistory.com

1. Persistence Context

1. Entity Manager Life Cycle Tests

EntityManagerFactory는 애플리케이션 당 한 개를 생성하는 것이 적절하므로 @BeforeAll 설정을 통해 모든 테스트가 실행되기 전 딱 한 번 호출하도록 한다. EntityManager는 요청 단위마다 생성하는 것이 적절하므로 @BeforeEach 설정을 통해 각각의 테스트 메소드가 실행되기 전 호출하도록 한다. 각각의 테스트 메소드가 실행된 후 호출되는 @AfterEach 설정을 통해 사용했던 EntityManager 객체를 반납하고 모든 테스트가 실행 된 후 딱 한 번 호출 되는 @AfterAll 설정을 통해 EntityManagerFactory 객체를 반납하도록 한다.

 

public class A_EntityManagerLifeCycleTests {

    private static EntityManagerFactory entityManagerFactory;
    private EntityManager entityManager;

    @BeforeAll
    public static void initFactory() {
        entityManagerFactory = Persistence.createEntityManagerFactory("jpatest");
    }

    @BeforeEach
    public void initManager() {
        entityManager = entityManagerFactory.createEntityManager();
    }

    @AfterAll
    public static void closeFactory() {
        entityManagerFactory.close();
    }

    @AfterEach
    public void closeManager() {
        entityManager.close();
    }
}

 

테스트를 2번 실행하며 EntityManagerFactory와 EntityManager의 해시코드를 출력해 라이프 사이클을 확인한다.

 

@Test
public void 엔터티_매니저_팩토리와_엔터티_매니저_생명주기_확인1() {
    System.out.println("entityManagerFactory.hashCode : " + entityManagerFactory.hashCode());
    System.out.println("entityManager.hashCode : " + entityManager.hashCode());
}

@Test
public void 엔터티_매니저_팩토리와_엔터티_매니저_생명주기_확인2() {
   System.out.println("entityManagerFactory.hashCode : " + entityManagerFactory.hashCode());
   System.out.println("entityManager.hashCode : " + entityManager.hashCode());
}

 

실행결과

 

entityManagerFactory.hashCode : 1135936028
entityManager.hashCode : 247334525
entityManagerFactory.hashCode : 1135936028
entityManager.hashCode : 1829344035

 

EntityManagerFactory는 같은 해시코드가 출력되는 것을 통해 하나의 객체로 처리되고 있고, EntityManager는 다른 해시코드가 출력 되는 것을 통해 매 요청마다 새로운 객체가 생성되고 있음을 확인할 수 있다.

728x90
반응형
728x90
반응형

[JPA] JPA란 무엇인가? Java Persistence API의 핵심 개념 정리 - 2

 

[JPA] JPA란 무엇인가? Java Persistence API의 핵심 개념 정리 - 2

[JPA] JPA란 무엇인가? Java Persistence API의 핵심 개념 정리 [JPA] JPA란 무엇인가? Java Persistence API의 핵심 개념 정리[Spring Security] Spring Security FilterChain 동작 원리 완전 해부 - 2 [Spring Security] Spring Security F

crushed-taro.tistory.com

1. Persistence Context

1. EntityManager

엔터티 매니저는 엔터티를 저장하는 메모리상의 데이터베이스이다. 엔터티 저장, 수정, 삭제, 조회 등 엔터티와 관련된 모든 일을 한다. 엔터티 매니저는 스레드 세이프 하지 않기 때문에 동시성 문제가 발생할 수 있어 스레드 간 공유 하면 안된다. 그래서 Web의 경우 일반적으로는 request scope와 일치 시킨다.

 

2. EntityManagerFactory

엔터티 매니저를 생성할 수 있는 기능을 제공하는 팩토리 클래스이다. 스레드 세이프 하기 때문에 여러 스레드가 동시에 접근해도 안전하므로 서로 다른 스레드 간 공유해서 재사용한다. 스레드 세이프 한 기능을 요청 스코프마다 생성하기에는 비용(시간, 메모리) 부담이 크기 때문에 application 스코프와 동일한 싱글톤으로 생성해서 관리하게 된다. 따라서 데이터 베이스를 사용하는 애플리케이션 당 한 개의 EntityManagerFactory를 생성한다.

 

3. PersistenceContext

엔터티를 영구 저장하는 환경을 말한다. 엔터티 매니저에 엔터티를 저장하거나 조회하면 엔터티 매니저는 영속성 컨텍스트에 엔터티를 보관하고 관리한다. 영속성 엔터티를 key value방식으로 저장하는 저장소 역할을 한다. 영속성 컨텍스트는 엔터티 매니저를 생성할 때 하나 만들어진다. 그리고 엔터티 매니저를 통해서 영속성 컨텍스트에 접근할 수 있고 영속성 컨텍스트를 관리할 수 있다.

 

4. persistence.xml 생성

persistence.xml 파일은 JPA의 설정 파일이다. 이 파일에는 엔티티 매니저 팩토리를 설정하기 위한 내용이 들어간다. persistence-unit 엘리먼트는 엔티티 매니저 팩토리를 식별하기 위한 이름을 지정하며, properties 엘리먼트는 데이터베이스 연결 정보와 hibernate 설정을 지정한다.

resources/META-INF/persistence.xml 파일을 아래와 같이 생성한다.

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.2">

	<!-- 엔티티 매니저 팩토리를 식별하기 위한 이름 설정 -->
	<persistence-unit name="jpatest">
		<properties>
			<!-- 데이터 베이스 연결 정보 -->
			<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
			<property name="javax.persistence.jdbc.user" value="{사용자 이름}"/>
			<property name="javax.persistence.jdbc.password" value="{비밀번호}"/>
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://{DBMS 호스트}:{포트}/{데이터베이스 이름}"/>
		  <!-- hibernate 설정 (실행 되는 sql 구문을 format 형태로 보여준다) -->
			<property name="hibernate.show_sql" value="true"/>
			<property name="hibernate.format_sql" value="true"/>
		</properties>
	
	</persistence-unit>

</persistence>

 

5. JUnit

JUnit은 단위 테스트를 위한 프레임워크이다. 코드의 품질을 개선하고 유지보수성을 높이기 위해 사용된다. JUnit은 메소드 단위로 테스트를 수행하며, 예상한 결과와 실제 결과를 비교하여 테스트를 수행한다. 이를 통해 개발자들은 코드의 문제점을 발견하고 수정할 수 있게 된다.

 

1. JUnit Annotation

  • @Test : 해당 메소드가 테스트 메소드임을 선언
  • @BeforeAll : 모든 테스트가 실행되기 전 딱 한 번 호출
  • @BeforeEach : 각각의 테스트 메소드가 실행되기 전 호출
  • @AfterAll : 모든 테스트가 실행된 후 딱 한 번 호출
  • @AfterEach : 각각의 테스트 메소드가 실행된 후 호출

2. JUnit Method

  • assertEquals() : 두 값이 동일한지 확인
  • assertArrayEquals() : 두 배열이 동일한지 확인
  • assertTrue() : 조건식이 true인지 확인
  • assertFalse() : 조건식이 false인지 확인
  • assertNotNull() : 값이 null이 아닌지 확인
  • assertNull() : 값이 null인지 확인
  • assertSame() : 두 객체가 같은 객체인지 확인
  • assertNotSame() : 두 객체가 다른 객체인지 확인
728x90
반응형
728x90
반응형

[JPA] JPA란 무엇인가? Java Persistence API의 핵심 개념 정리

 

[JPA] JPA란 무엇인가? Java Persistence API의 핵심 개념 정리

[Spring Security] Spring Security FilterChain 동작 원리 완전 해부 - 2 [Spring Security] Spring Security FilterChain 동작 원리 완전 해부 - 2[Spring Security] Spring Security FilterChain 동작 원리 완전 해부 [Spring Security] Spring Se

crushed-taro.tistory.com

1. JPA(Java Persistence API) 개요

1. JPA의 원리

1. JPA의 기본 동작방식

  • Java 애플리케이션과 JDBC사이에서 동작하며 내부적으로 JDBC API를 활용한다.
  • JPA는 엔티티를 저장하는 환경인 영속성 컨텍스트(Persistence Context)를 통해 엔티티를 보관하고 관리한다.

JPA 1

엔티티(Entity) 
@Entity, @Table, @Id, @Column과 같은 어노테이션을 통해 SQL이 아닌 DB 테이블과 매핑되게 작성된 클래스

 

2. 엔티티의 영속성 컨텍스트(Persistence Context)에서의 생명주기

JPA 2

  • 엔티티 메니저가 엔티티를 저장하는 공간으로 엔티티를 보관하고 관리한다.
  • 엔티티 매니저가 생성될 때 하나의 영속성 컨텍스트가 만들어 진다.
  • 엔티티의 생명주기
상태 설명
비영속(new/transient) 엔티티가 영속성 컨텍스트와 전혀 관계가 없는 상태
영속(managed) 엔티티가 영속성 컨텍스트에 저장된 상태 
준영속(detached) 영속성 컨텍스트에 저장되었다가 분리된 상태
삭제(removed) 엔티티가 삭제된 상태
병합(merge) 엔티티가 준영속 상태인 엔티티가 다시 영속상태로 변경된 상태

 

3. 영속성 컨텍스트가 엔티티를 관리하는 원리

JPA 3

 

  • 1차 캐시2
    • 영속성 컨텍스트 내부에 Map으로 관리되는 캐시(key는 @Id이며 매핑한 식별자이고 value은 엔티티 인스턴스이다.)이며 이 곳에 있는 엔티티는 캐시에서 바로 불러와서 조회 성능이 올라간다.
  • 동일성 보장
    • 반복해서 호출 시 1차 캐시에서 같은 엔티티 인스턴스를 가져올 수 있다.
  • 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
    • (엔티티 등록(INSERT)을 예로 들면) 엔티티 매니저는 트랜잭션을 커밋하기 직전까지 데이터베이스에 저장(flush) 대신 쓰기 지연 SQL 저장소에 INSERT SQL을 차곡차곡 쌓게 되며 커밋 시에 쿼리를 데이터베이스로 보내는데 이를 트랜잭션을 지원하는 쓰기 지연이라고 한다.
    • 플러시(flush): flush()는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다.
    • 플러시 절차
      1. 영속성 컨텍스트에 보관할 때 최초 엔티티 상태를 복사해서 스냅샷으로 저장해 두고 모든 엔티티를 스냅샷과 비교해서 수정된 엔티티를 찾아서 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 보낸다.
      2. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 저장한다.
      3. 플러시를 하는 경우
        1. em.flush()를 직접 호출한다.
        2. 트랜잭션 커밋 시 플러시가 자동 호출한다.
        3. JPQL 쿼리 실행 시 플러시가 자동 호출한다.
  • 변경 감지(dirty checking)
    • SQL에 의존적이지 않도록 엔티티의 데이터 변경을 감지하고 데이터베이스에 자동으로 반영하는 기능을 변경 감지라고 한다. 영속성 컨텍스트에 보관할 때 최초 엔티티 상태를 복사해서 저장한 스냅샷과 이를 비교하여 감지한다. 영속 상태의 엔티티에만 적용된다.(준영속이나 비영속은 해당되지 않는다.)
    • 변경 감지 절차(커밋 실행 시)
      1. 우선 엔티티 매니저 내부에서 먼저 플러시(flush)가 호출된다.
      2. 엔티티와 스냅샷을 비교해서 변경된 엔티티를 찾는다.
      3. 변경된 엔티티와 관련된 수정 쿼리를 생성해서 쓰기 지연 SQL 저장소에 보낸다.
      4. 쓰기 지연 저장소의 SQL을 데이터베이스로 보낸다.
      5. 데이터베이스에서 트랜잭션을 커밋한다.
728x90
반응형
728x90
반응형

[Spring Security] Spring Security FilterChain 동작 원리 완전 해부 - 2

 

[Spring Security] Spring Security FilterChain 동작 원리 완전 해부 - 2

[Spring Security] Spring Security FilterChain 동작 원리 완전 해부 [Spring Security] Spring Security FilterChain 동작 원리 완전 해부1. Security Filter1. Security Filter 개요1. Security Filter 주요 역할일련의 서블릿 필터 체인

crushed-taro.tistory.com

1. JPA(Java Persistence API) 개요

1. JPA란?

  • 자바 진영의 ORM(Object Relational Mapping) 기술 표준으로 ORM 기술을 사용하기 위한 표준 인터페이스의 모음이다.
  • ORM은 자바 객체와 DB테이블을 매핑하고 자바 객체간의 관계를 토대로 SQL을 생성 및 실행 할 수 있으며 대중적인 언어에는 대부분 ORM 기술이 존재한다.
  • JPA 2.1 기준 표준 명세를 구현한 구현체들(Hibernate, EclipseLink, DataNucleus) 중에 대부분 Hibernate를 사용하므로 JPA를 활용하기 위해서는 Hibernate를 사용하게 된다.
ORM(Object relational mapping)

객체-관계 매핑. 자바 플랫폼 SE와 EE를 사용하는 응용프로그램에서 객체는 객체 지향적으로 설계하고 관계형 데이터베이스는 관계형 데이터베이스의 패러다임대로 설계할 수 있도록 중간에서 매핑을 해주는 기술을 말한다.

 

JPA 1

 

2. JPA 역사

  • 1997년 IBM에서 개발되었고 1999년에 Sun Microsystems로 인수된 EJB(Enterprise JavaBeans)라는 자바 표준이 있었는데 지저분한 코드와 느리고 제대로 동작하지도 않는 결함이 많은 기술이었다.
  • Gavin King이 EJB 컨테이너에 의존하지 않는 ORM 프레임워크인 Hibernate를 만들게 되고 오픈소스화가 되어 EJB는 사라지게 되었다.
  • 이후 Java와 GavinKing이 같이 Java표준을 만들게 되었고 2006년에 JPA 1.0이라는 JPA의 초기버전이 나온 이후 현재까지 JPA는 2.1버전까지 사용되고 있다.
EJB(Enterprise JavaBeans)

 비지니스로직과 시스템 서비스를 이용하는 로직을 분산하고 그 사이의 규약을 정의한 것으로 비지니스 로직을 탑제한 부분을 'Enterprise Bean'이라고 부르며 Database 및 Transaction 처리와 같은 시스템 서비스 로직을 탑제한 부분을 'Container'라고 부른다.

 

3. JPA의 특징

  • 영속성 컨텍스트가 엔티티를 생명주기를 통해 관리한다.
  • native SQL을 통해 직접 SQL을 해당 DB에 맞게 작성할 수도 있다.
  • DBMS별로 dialect(방언, 사투리)를 제공한다.

JPA 2

 

4. JPA의 사용 이유

1. JPA의 장점

  • 객체지향과 관계지향이라는 서로 다른 패러다임 불일치를 해소해 주며 SQL 중심이 아닌 객체지향 패러다임 중심의 개발이 가능하다.
  • 개발자가 직접 SQL을 따로 작성하지 않아도 SQL문을 작성해 주므로 생산성이 향상된다.
  • SQL을 수정할 필요가 없으므로 설정 및 필드 변경시 SQL이 자동 수정되어 유지보수가 향상된다.
  • DB의 종류에 따라 SQL문에 있어 다소 차이가 있지만 JPA는 개발자 대신 이를 판단하고 해당 DB에 맞는 SQL을 작성해 준다.
  • 캐시를 활용한 성능 최적화로 인해 트랜잭션을 처리하는 시간이 굉장히 많이 단축된다.

2. JPA의 단점

  • 너무 복잡한 SQL을 작성하기에는 적합하지 않다.
  • JPA를 제대로 이해하지 못하고 작성시 성능저하가 발생할 수 있다.
  • 객체지향 패러다임과 관계형 데이터베이스 패러다임에 대한 이해가 없는 상태로는 제대로 이해할 수 없다.
  • 복잡한 동적 SQL같은 경우 순수 JPA만으로는 부족한 부분에 있어 추가 라이브러리를 활용해야 할 경우가 생길 수 있다.

 

5. 마이바티스(MyBatis)와 JPA

  • Mybatis는 SQL Mapper로 SQL Mapping을 사용하는 영속성(DB저장) 프레임워크이다. 개발자가 직접 SQL코드를 작성하고 객체에 대해 매핑을 위한 설정을 모두 직접 처리해야 한다. 또한, 수정이 이루어질 시 SQL뿐 아니라 매핑 될 객체까지 같이 수정해야 하는 번거로움이 있다.
  • JPA와 마이바티스는 분류상 서로 다르다. JPA는 ORM 기술이고, Mybatis는 SQL Mapper의 한 종류이다.
  • 어플리케이션이 고도화 되면 JPA를 구현하여 손이 많이 가는 것 보다 Mybatis가 답이 될 수도 있다. (JPA가 무조건 좋은 것이 아니다. 다만 JPA는 추가 라이브러리를 활용하면 복잡한 SQL이나 동적 SQL에 있어서 도움을 받을 수 있다.)
728x90
반응형

+ Recent posts