Closed emiling closed 3 years ago
EntityManager
는 영속성 컨텍스트를 관리합니다.
앱 컨텍스트가 빈을 관리하듯 영속성 컨텍스트는 엔터티 인스턴스를 관리합니다.
영속성 컨텍스트는 하이버네이트의 Session
과 비슷합니다. Session
은 직접 조작을 할 수 있지만 영속성 컨텍스트는 그렇지 않습니다. 대신 EntityManager
를 통해야 합니다.
EntityManagerFactory
를 생성하는 팩토리 빈입니다. 영속성 유닛 정의에 기반하여 설정합니다.
EntityManagerFactory
는 하이버네이트의 SessionFactory
와 비슷합니다.
챕터9에서 자세히 설명.
EntifyManager
의 구성 정보는 영속성 유닛이라 불립니다. 앱은 여러 개의 영속성 유닛을 정의할 수 있습니다.
EntityManager
는 EntityManagerFactory
에서 획득하고, EntityManagerFactory
는 EntityManagerFactoryBean
에서 획득하므로 보통 팩토리 빈을 구성할 시 영속성 유닛을 알려주면 됩니다.
영속성 유닛은 META-INF/persistence.xml
에 정의되는 것이 스펙입니다. 스프링3.1부터는 엔터티 스캔을 통하여 영속성 유닛을 구성하게 되어 persistence.xml
이 아예 필요하지 않을 수 있습니다.
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="guestbook">
<provider>
oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
</provider>
<class>kame.springguestbook.service.Message</class>
<properties>
<property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="toplink.jdbc.url"
value="jdbc:mysql://localhost/test?characterEncoding=euckr" />
<property name="toplink.jdbc.user" value="root" />
<property name="toplink.jdbc.password" value="root" />
</properties>
</persistence-unit>
</persistence>
LocalEntityManagerFactoryBean
클래스 사용하기
해당 클래스의 빈을 구성할 때 영속성 유닛의 이름을 기재하면 됩니다.
이 클래스는DataSource
주입이 불가능하여 persistence.xml
정보만을 그대로 사용하게 됩니다.
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="guestbook" />
</bean>
JEE 호환 컨테이너가 제공하는 EntityMangerFactory
를 사용하는 것입니다.
호환 컨테이너에서 영속성 유닛이 부트스트랩 됨> 스프링에서 해당 객체를 룩업하여 빈 등록하도록 구성하면 됩니다.
<beans ...>
<jee:jndi-lookup id="prospring5Emf"
jndi-name="persistence/prospring5PersistenceUnit" />
</beans>
LocalContainerEntityManagerFactoryBean
클래스를 사용하기
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="guestbook" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
</bean>
</property>
</bean>
이 클래스는 DataSource
주입이 가능합니다. 또 여러 프로퍼티 값들을 필요로 합니다.
persistenceUnitName persistence.xml에 정의된 영속성 유닛 이름.
LocalContainerEntityManagerFactoryBean
빈 구성 시, DataSource
와 Vendor를 설정하기 때문에 persistence.xml
파일은 엔터티 매핑 정보만 갖고 있으면 됩니다.
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="guestbook" transaction-type="RESOURCE_LOCAL">
<class>kame.spring.guestbook.service.Message</class>
</persistence-unit>
</persistence>
packagesToSacn
어노테이션이 붙은 도메인 객체를 스캔할 범위를 지정합니다.
이 방법을 채용할 경우persistence.xml
에 매핑 정보가 필요 없게 되고, 아예 영속성 유닛을 정의하지 않아도 됩니다!
dataSource 데이터베이스 연동을 위한 DataSource
jpaVendorAdapter JPA API 구현체 Adapter
jpaProperties 영속성 제공자의 세부 설정 정보.
loadTimeWeaver JPA의 ClassTransformer 규약에 맞춰 클래스를 조작할 때 사용될 LoadTimeWeaver를 설정. 하이버네이트 EntityManager의 경우 : LoadTimeWeaver를 필요로 하지 않음. TopLink를 이용하는 경우 : 상황에 따라 알맞은 LoadTimeWeaver 객체를 설정 해주어야 함.
스프링이 제공하는 JpaTransactionManager
빈을 등록해서 사용합시다.
프로퍼티로 EntityManagerFactory
를 요구합니다. 그런데 구성에는 EntityManagerFactory
빈이 없습니다.
대신 EntityManagerFactoryBean
즉, 팩토리 빈을 넘겨줘야 합니다.
어노테이션 기반 트랜잭션 경계를 활성하기 위해
<tx:annotation-drive>
태그나 @EnableTransactionManager
을 선언합니다.
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManger">
<property name="entityManagerFactory" ref="emf" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
~EntityManagerFactoryBean
팩토리 빈의 명명을 보면 이 친구가 EntityManager
를 뱉어낼 것 같지만
사실 getObject()
메서드를 보면 싱글턴 EntityManagerFactory
를 뱉어냅니다.
~EntityManagerFactoryBean
-> EntityManagerFactory
-> EntityManager
-> 영속성 컨텍스트 순으로 관리되는 양상입니다.
우리가 EntityManager
를 획득하여 사용하려면
EntityManager
타입인 필드에 @PersistenceContext
어노테이션을 붙여서 주입 받아야 합니다.
영속성 유닛이 여러 개 정의되어 있다면 unitName
프로퍼티를 지정할 수 있고
@Autowired + @Qualifier
조합도 이용 가능합니다.
@Repositoy
public class SingerSerivceImple implements SingerService {
...
@PersistenceContext
private EntityManager em;
@Transactional(readOnly=true)
@Override
public List<Singer> findAll() {
return em.createNamedQuery(Singer.FIND_ALL, Singer.class).getResultList();
}
주제
[8장] 스프링에서 JPA2로 데이터 액세스하기 (1) 를 읽고 중요✨ 하다고 생각하는 키워드와 선택한 이유에 대해서 코멘트로 달아주세요
연관챕터
61