1. Hibernate란?
- Hibernate는 JPA를 구현한 ORM 라이브러리들 중 하나다.
- Spring과 Hibernate는 비슷한 시기에 POJO 프로그래밍을 바탕으로 자바 엔터프라이즈 개발의 혁신을 가져온 대표적인 기술이다.
2. SessionFactory
1) SessionFactory란?
- Hibernate의 핵심 엔진 역할을 하는 인터페이스다.
- SessionFactory는 bean으로 등록된 DataSource를 이용하여 spring이 제공하는 트랜잭션 매니저와 연동할 수 있도록 설정되어 있다.
- Spring에서는 SessionFactory bean을 생성해주는 LocalSessionFactoryBean과 AnnotationSessionFactoryBean을 제공한다.
2) SessionFactoryBean
(1) LocalSessionFactoryBean
- 다음 예시와 같이 매핑파일 목록과 프로퍼티를 담은 hibernate.cfg.xml 설정 파일을 이용한다.
<hibernate.cfg.xml>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.pool_size">1</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping resource=".../Member.hbm.xml" />
<!-- mapping class="com.example.demo.hibernate.Member" / -->
</session-factory>
</hibernate-configuration>
※ mapping 파일 경로의 기준은 classpath이다.
- <mapping>의 resource 속성을 사용하면 클래스와 테이블 사이의 매핑 정보를 담고 있는 xml 설정 파일들을 등록할 수도 있다. 예를 들어, 매핑 파일에는 다음과 같은 내용이 들어갈 수 있다.
<Member.hbm.xml>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example.demo.hibernate">
<class name="Member" table="MEMBER">
<id name="id" column="ID" />
<property name="name" column="NAME" length="20" />
<property name="point" column="POINT" not-null="false" type="double" />
</hibernate-mapping>
- 기본적인 SessionFactory bean은 DataSource bean과 hibernate.cfg.xml 파일을 이용하여 생성할 수 있는데,
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value=".../hibernate.cfg.xml" />
</bean>
만약 hibernate.cfg.xml 파일을 생략하고 싶다면 아래 두 프로퍼티들을 이용하면 된다.
<1> mappingLocations
- hibernate.cfg.xml에 있는 <mapping> 태그를 이용하는 대신 mappingLocations라는 이름의 프로퍼티를 사용하는 방법으로, 아래와 같이 <list><value> 형식으로 여러 매핑 파일들을 지정할 수 있다.
<property name="mappingLocations">
<list>
<value>[매핑 파일1 경로]</value>
<value>[매핑 파일2 경로]</value>
</list>
</property>
<2> hibernateProperties
- hibernate.cfg.xml 안에 넣어주는 DB 설정 값을 hibernateProperties라는 이름의 프로퍼티를 통해서 지정하는 방법이다. Properties 타입이므로 <props><prop> 형식을 이용하여 프로퍼티를 추가하면 된다.
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="connection.pool_size">1</prop>
<prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="show_sql">true</prop>
<prop key="hbm2ddl.auto">create</prop>
</props>
</property>
- LocalSessionFactoryBean에는 캐시 프로바이더, 이벤트 리스너와 같은 프로퍼티들도 제공된다.
(2) AnnotationSessionFactoryBean
- xml 매핑 파일 대신 어노테이션을 이용하여 SessionFactory를 생성하는 방법이다.
- 기본적인 property들의 설정 방법은 LocalSessionFactoryBean과 동일하며, 추가로 annotatedClasses, packageToScan 프로퍼티가 제공된다.
<1> annotatedClasses
- @Entity와 같은 매핑 어노테이션이 부여된 클래스의 목록을 지정한다.
<property name="annotatedClasses">
<list>
<value>[매핑 클래스 경로]</value>
<value>[매핑 클래스 경로]</value>
</list>
</property>
<2> packagesToScan
- 해당 패키지 내에 있는 @Entity 클래스들을 자동으로 찾아서 등록해준다.
<property name="packageToScan" value="com.example.demo.hibernate" />
3) TransactionManager
- SessionFactory를 이용하여 DAO를 만들 때 트랜잭션을 적용하려면 트랜잭션 매니저가 필요하다. Hibernate에 적용할 수 있는 트랜잭션 매니저로는 아래 두 가지가 있다.
(1) HibernateTransactionManager
- 단일 DB를 사용하고 JTA를 이용할 필요가 없을 때 사용된다.
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
- JDBC DAO와 동일한 DataSource를 사용한다면 같은 트랜잭션을 공유할 수도 있다.
(2) JtaTransactionManager
- 서버가 제공하는 글로벌 트랜잭션 기능을 이용할 때 사용된다.
- JtaTransactionManager는 DataSource나 SessionFactory 등의 bean을 참조하지 않고, JNDI를 통하여 서버에 등록된 TransactionManager와 UserTransaction을 가져와서 JTA로 트랜잭션을 관리해준다.
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
※ TransactionManager의 디폴트 JNDI 이름은 java:comp/TransactionManager, java:appserver/TransactionManager, java:pm/TransactionManager, java:/TransactionManager으로 총 4개가 있고, UserTransaction의 디폴트 JNDI 이름은 java:comp/UserTransaction이다. 디폴트 이름을 쓰지 않는다면 transactionManagerName과 userTransactionName 프로퍼티로 이름을 지정해준다.
- WAS의 지원 없이도 애플리케이션 안에 JTA 기능을 내장하는 독립형 JTA 방식도 존재한다. 이 방식에서는 XA를 지원하는 XA DataSource를 사용해야 하고, TransactionManager bean과 UserTransaction bean을 직접 만들어야 한다.
※ 독립형 JTA 트랜잭션 매니저로는 대표적으로 JOTM과 Atomikos가 있다. Atomikos를 이용하는 예시는 https://m.blog.naver.com/xcv1524/220508445415를 참고하자.
3. Session
- Hibernate의 핵심 API
- SessionFactory로부터 생성되며 일반적으로 트랜잭션과 동일한 스코프를 갖는다. Hibernate DAO는 spring이 관리하는 트랜잭션과 동기화된 Session을 가져와서 사용한다.
- Session을 생성하는 방법으로는 HibernateTemplate를 사용하는 방법과 SessionFactory의 getCurrentSession() 메소드를 사용하는 방법이 있다.
1) HibernateTemplate
- SessionFactory를 생성자로 넣어 생성한다.
- HibernateDaoSupport 클래스를 상속하면 getHibernateTemplate() 메소드를 통해 템플릿 오브젝트를 가져올 수 있다.
- Session의 대부분의 기능을 메소드를 통해 이용할 수 있게 해준다.
- 자동커밋 방식으로 동작한다.
- Hibernate가 제공하는 API를 직접 사용하지 못하고 템플릿 구조에 종속된다는 단점이 있다.
사용 예시
public void addMember(Member member) {
hibernateTemplate.save(member);
}
2) SessionFactory의 getCurrentSession() 메소드
- 현재 진행 중인 트랜잭션에 연결되어 있는 hibernate Session을 반환해준다.
- Spring API가 아닌 hibernate의 API를 사용하는 방법이다.
- 트랜잭션이 시작된 후에만 사용할 수 있다는 단점이 있다.
사용 예시
public void addMember(Member member) {
sessionFactory.getCurrentSession().save(member);
}
● 참고 자료 : 토비의 스프링 3.1 Vol.2
'Spring Series > Spring Framework' 카테고리의 다른 글
[Spring] DispatcherServlet의 DI 전략 (0) | 2022.07.13 |
---|---|
[Spring] @Transactional의 속성 (0) | 2022.07.09 |
[Spring] Spring이 제공하는 JPA (0) | 2022.07.02 |
[Spring] 더 편리해진 Spring JDBC (0) | 2022.06.29 |
[Spring] .gitignore 적용하기 (0) | 2022.06.29 |
댓글