4. [JPA] 엔티티 매니저 팩토리

프로그래밍|2017. 8. 10. 14:09



What is the EntityManagerFactory?

1. 엔티티 매니저 팩토리는 엔티티 매니저를 관리한다.

 > 이름 그대로 엔티티를 관리하는 관리자다.

 > 엔티티 매니저는 엔티티를 저장하고, 수정하고, 삭제하고, 조회하는 등 엔티티와 관련된 모든 일을 처리한다. (쉽게 말해서 JDBC의 Connection 객체로 생각하면 된다.)

 

2. 엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야 한다.

 > 애플리케이션에서 바라보는 DB가 한 개라면 엔티티 매니저 팩토리도 한 개이다.

 

3. 엔티티 매니저 팩토리는 여러 쓰레드가 동시에 접근해도 안전하므로 서로 다른 쓰레드 간에 공유해도 된다.

테스트 코드를 통해서 엔티티 매니저 팩토리에 대해서 더 알아보자.


다음과 같이 @PersistenceUnit 애노테이션을 이용하여 엔티티 매니저 팩토리를 주입 받을 수 있다.

1
2
@PersistenceUnit
private EntityManagerFactory emf;
cs


아래와 같이 엔티티 매니저 팩토리의 기본 속성 정보들을 확인해 보자.

1
2
3
4
@Test
public void 엔티티매니저팩토리_속성_정보_확인() {
    emf.getProperties().forEach((k, v) -> System.out.println("key : " + k + ", value : " + v));
}
cs


특별하게 보이는 것은 hibernate.connection.datasource 키 정보이다.

커넥션 풀 설정을 application.yml에 하지 않았는데도 다음과 같이 tomcat jdbc pool을 생성해 준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
key : hibernate.connection.datasource, value : org.apache.tomcat.jdbc.pool.DataSource@51f49060{ConnectionPool[defaultAutoCommit=null; defaultReadOnly=null; 
defaultTransactionIsolation=-1; defaultCatalog=null; driverClassName=org.h2.Driver; 
maxActive=100; maxIdle=100; minIdle=10; initialSize=10; 
maxWait=30000; testOnBorrow=true; testOnReturn=false; timeBetweenEvictionRunsMillis=5000; 
numTestsPerEvictionRun=0; minEvictableIdleTimeMillis=60000; testWhileIdle=false; testOnConnect=false; 
password=********; url=jdbc:h2:mem:nkdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE; 
username=sa; validationQuery=SELECT 1; validationQueryTimeout=-1; validatorClassName=null; 
validationInterval=3000; accessToUnderlyingConnectionAllowed=true; removeAbandoned=false; 
removeAbandonedTimeout=60; logAbandoned=false; connectionProperties=null; initSQL=null; 
jdbcInterceptors=null; jmxEnabled=true; fairQueue=true; useEquals=true; abandonWhenPercentageFull=0; 
maxAge=0; useLock=false; dataSource=null; dataSourceJNDI=null; suspectTimeout=0; 
alternateUsernameAllowed=false; commitOnReturn=false; rollbackOnReturn=false; 
useDisposableConnectionFacade=true; logValidationErrors=false; propagateInterruptState=false; ignoreExceptionOnPreLoad=false; }
cs


여기서 궁금한 것은 왜 tomcat jdbc pool을 생성할까?

이유는 pom.xml에 dependency로 추가한 spring-boot-starter-data-jpa 때문이다.

spring-boot-starter-data-jpa > spring-boot-starter-jdbc > tomcat-jdbc 라이브러리가 존재한다.


다음은 엔티티 매니저 팩토리가 한 개만 존재하는지를 확인하는 테스트 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@PersistenceUnit
private EntityManagerFactory emf;
 
@PersistenceContext
private EntityManager em;
 
@Resource(name = "EntityManagerFactoryMemberService")
private MemberService memberService;
 
@Test
public void 엔티티매니저팩토리_인스턴스_체크() {
    assertThat(emf, is(sameInstance(memberService.getEmf())));
    assertThat(emf, is(sameInstance(memberService.getEmf2())));
    assertThat(memberService.getEmf(), is(sameInstance(memberService.getEmf2())));
}
    
@Service("EntityManagerFactoryMemberService")
class MemberService {
    
    @Getter
    @PersistenceUnit
    private EntityManagerFactory emf;
    
    @Getter
    @PersistenceUnit
    private EntityManagerFactory emf2;
    
    @Getter
    @PersistenceContext
    private EntityManager em;
}
cs


테스트 코드에서와 같이 엔티티 매니저 팩토리를 여러 군대에서 주입 받아도 인스턴스 객체는 항상 같다.



[참고]

https://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html_single/

1
2
3
4
5
An entity manager factory provides entity manager instances, 
all instances are configured to connect to the same database, 
to use the same default settings as defined by the particular implementation, 
etc. You can prepare several entity manager factories to access several data stores. 
This interface is similar to the SessionFactory in native Hibernate.
cs


'프로그래밍' 카테고리의 다른 글

8. [JPA] Attribute Converter  (0) 2017.08.23
7. [JPA] fetch type - 로딩 기법  (0) 2017.08.21
6. [JPA] 영속성 전이 - Cascade  (0) 2017.08.17
5. [JPA] 엔티티 매니저  (0) 2017.08.16
3. [JPA] 영속성 컨텍스트란?  (0) 2017.08.01
2. [JPA] 테스트 환경  (0) 2017.07.21
1. [JPA] 사용 경험  (2) 2017.07.21
spark framework  (0) 2016.09.28

댓글()