웹사이트 검색

Spring Hibernate 통합 예제 자습서(Spring 4 + Hibernate 3 및 Hibernate 4)


봄 동면

오늘 이 튜토리얼에서는 Spring 4를 사용하고 Hibernate 3과 통합한 다음 동일한 프로젝트를 Hibernate 4를 사용하도록 업데이트합니다. , 내 프로젝트에서 사용한 모든 종속성을 나열하는 것이 좋습니다. 모든 봄 및 최대 절전 모드 버전이 호환되지 않는 것으로 나타났습니다. 아래 버전은 저에게 적합하므로 호환된다고 생각합니다. 일부 다른 버전을 사용 중이고 java.lang.NoClassDefFoundError가 발생하는 경우 호환되지 않는다는 의미입니다. 대부분 Hibernate 클래스가 한 패키지에서 다른 패키지로 이동되어 이 오류가 발생하기 때문입니다. 예를 들어 org.hibernate.engine.FilterDefinition 클래스는 최신 Hibernate 버전에서 org.hibernate.engine.spi.FilterDefinition으로 이동되었습니다.

  • 스프링 프레임워크 버전: 4.0.3.RELEASE
  • Hibernate 코어 및 Hibernate EntityManager 버전: 3.6.9.Final 및 4.3.5.Final
  • 봄 ORM 버전: 4.0.3.RELEASE

데이터베이스 설정

내 프로젝트에 MySQL 데이터베이스를 사용하고 있으므로 setup.sql 스크립트 아래에서 이 예제에 필요한 테이블을 생성합니다.

CREATE TABLE `Person` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '',
  `country` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
commit;

Spring Hibernate 통합 예제 프로젝트 구조

메이븐 종속성

필요한 모든 종속성과 해당 버전에 대해 먼저 pom.xml 파일을 살펴보겠습니다.

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.springframework.samples</groupId>
	<artifactId>SpringHibernateExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>

		<!-- Generic properties -->
		<java.version>1.6</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

		<!-- Spring -->
		<spring-framework.version>4.0.3.RELEASE</spring-framework.version>

		<!-- Hibernate / JPA -->
		<!-- <hibernate.version>4.3.5.Final</hibernate.version> -->
		<hibernate.version>3.6.9.Final</hibernate.version>

		<!-- Logging -->
		<logback.version>1.0.13</logback.version>
		<slf4j.version>1.7.5</slf4j.version>

	</properties>

	<dependencies>
		<!-- Spring and Transactions -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<!-- Spring ORM support -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<!-- Logging with SLF4J & LogBack -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>${logback.version}</version>
			<scope>runtime</scope>
		</dependency>

		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.9</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
	</dependencies>
</project>

Spring 및 Hibernate 통합 프로젝트의 중요한 종속성은 다음과 같습니다.

  • 핵심 Spring 기능을 위한 spring-context 및 spring-tx. 저는 4.0.3.RELEASE 버전을 사용하고 있습니다.
  • Spring ORM 지원을 위한 spring-orm 종속성, Spring 프로젝트의 최대 절전 모드 통합에 필요합니다.
  • Hibernate 프레임워크에 대한 hibernate-entitymanager 및 hibernate-core 종속성. 버전은 3.6.9.Final입니다. Hibernate 4를 사용하려면 위의 pom.xml 파일에 설명된 대로 버전을 4.3.5.Final로 변경하기만 하면 됩니다.
  • 데이터베이스 연결용 MySQL 드라이버용 mysql-connector-java.

모델 클래스 또는 엔티티 Bean

Hibernate XML 기반 매핑과 JPA 주석 기반 매핑을 사용할 수 있습니다. 여기서는 Hibernate가 JPA 구현을 제공하기 때문에 매핑을 위해 JPA 주석을 사용하고 있습니다.

package com.journaldev.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * Entity bean with JPA annotations
 * Hibernate provides JPA implementation
 * @author pankaj
 *
 */
@Entity
@Table(name="Person")
public class Person {

	@Id
	@Column(name="id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	private String name;
	
	private String country;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}
	
	@Override
	public String toString(){
		return "id="+id+", name="+name+", country="+country;
	}
}

DAO 클래스

우리는 DAO 클래스에서 두 가지 방법을 구현할 것입니다. 첫 번째는 Person 개체를 테이블에 저장하고 두 번째는 테이블에서 모든 레코드를 가져와 Person 목록을 반환하는 것입니다.

package com.journaldev.dao;

import java.util.List;

import com.journaldev.model.Person;

public interface PersonDAO {

	public void save(Person p);
	
	public List<Person> list();
	
}

위의 DAO 클래스 구현은 아래와 같습니다.

package com.journaldev.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.journaldev.model.Person;

public class PersonDAOImpl implements PersonDAO {

	private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
    
	@Override
	public void save(Person p) {
		Session session = this.sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		session.persist(p);
		tx.commit();
		session.close();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Person> list() {
		Session session = this.sessionFactory.openSession();
		List<Person> personList = session.createQuery("from Person").list();
		session.close();
		return personList;
	}

}

이것이 우리가 Hibernate 관련 클래스를 사용하고 있는 유일한 장소임을 주목하십시오. 이 패턴을 통해 우리의 구현은 유연하고 한 기술에서 다른 기술로 쉽게 마이그레이션할 수 있습니다. 예를 들어 iBatis ORM 프레임워크를 사용하려면 iBatis용 DAO 구현을 제공한 다음 스프링 빈 구성 파일을 변경하기만 하면 됩니다. 위의 예에서는 Hibernate 세션 트랜잭션 관리를 사용하고 있습니다. 그러나 @Transactional 주석을 사용하여 Spring 선언적 트랜잭션 관리를 사용할 수도 있습니다. 자세한 내용은 Spring 트랜잭션 관리를 참조하십시오.

Hibernate 3 통합을 위한 Spring Bean 구성 파일

먼저 Hibernate 3 통합에 필요한 스프링 빈 구성을 살펴보고 나중에 자세히 살펴보겠습니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:aop="https://www.springframework.org/schema/aop"
	xmlns:tx="https://www.springframework.org/schema/tx"
	xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/TestDB" />
		<property name="username" value="pankaj" />
		<property name="password" value="pankaj123" />
	</bean>

<!-- Hibernate 3 XML SessionFactory Bean definition-->
<!-- 	<bean id="hibernate3SessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="mappingResources">
			<list>
				<value>person.hbm.xml</value>
			</list>
		</property>
		<property name="hibernateProperties">
			<value>
				hibernate.dialect=org.hibernate.dialect.MySQLDialect
			</value>
		</property>
	</bean> -->

<!-- Hibernate 3 Annotation SessionFactory Bean definition-->
	<bean id="hibernate3AnnotatedSessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="annotatedClasses">
			<list>
				<value>com.journaldev.model.Person</value>
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.current_session_context_class">thread</prop>
				<prop key="hibernate.show_sql">false</prop>
			</props>
		</property>
	</bean>
	
	<bean id="personDAO" class="com.journaldev.dao.PersonDAOImpl">
		<property name="sessionFactory" ref="hibernate3AnnotatedSessionFactory" />
	</bean>
</beans>

Hibernate에 데이터베이스 연결 세부 정보를 제공할 수 있는 두 가지 방법이 있습니다. 첫 번째는 hibernateProperties에 모든 것을 전달하고 두 번째는 DataSource를 생성한 다음 이를 최대 절전 모드로 전달하는 것입니다. 저는 두 번째 접근 방식을 선호합니다. 이것이 데이터베이스 연결 속성을 설정하여 BasicDataSource를 생성하기 위해 Apache Commons DBCP 종속성이 있는 이유입니다. Spring 및 Hibernate 3 통합을 위해 Spring ORM은 하이버네이트 매핑이 XML 기반일 때 org.springframework.orm.hibernate3.LocalSessionFactoryBeanorg.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean의 두 클래스를 제공합니다. 는 주석 기반 매핑용입니다. XML 기반 매핑을 사용하는 경우 주석에 LocalSessionFactoryBean의 간단한 빈 구성을 제공했습니다. AnnotationSessionFactoryBeanLocalSessionFactoryBean 클래스를 확장하므로 최대 절전 모드 통합을 위한 모든 기본 속성을 갖습니다. 속성은 자체적으로 이해되며 대부분 최대 절전 모드와 관련되어 있으므로 자세한 내용은 다루지 않겠습니다. 그러나 hibernateProperties, annotatedClasses가 어디에서 오는지 궁금하다면 bean 클래스 소스 코드를 살펴봐야 합니다. 앞서 말했듯이 personDAO의 빈 정의에 주목하십시오. 다른 ORM 프레임워크로 전환해야 한다면 여기에서 구현 클래스를 변경하고 필요한 다른 속성을 설정해야 합니다.

Spring 4 Hibernate 3 테스트 프로그램

이제 설정이 준비되었습니다. 애플리케이션을 테스트하기 위한 간단한 프로그램을 작성해 보겠습니다.

package com.journaldev.main;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.journaldev.dao.PersonDAO;
import com.journaldev.model.Person;

public class SpringHibernateMain {

	public static void main(String[] args) {

		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
		
		PersonDAO personDAO = context.getBean(PersonDAO.class);
		
		Person person = new Person();
		person.setName("Pankaj"); person.setCountry("India");
		
		personDAO.save(person);
		
		System.out.println("Person::"+person);
		
		List<Person> list = personDAO.list();
		
		for(Person p : list){
			System.out.println("Person List::"+p);
		}
		//close resources
		context.close();	
	}
}

위의 프로그램을 실행하면 로깅을 제대로 설정하지 않았기 때문에 Hibernate와 관련된 많은 출력을 얻지만 이 튜토리얼의 범위를 벗어납니다. 그러나 프로그램에서 생성된 다음 출력을 얻습니다.

Person::id=3, name=Pankaj, country=India
Person List::id=1, name=Pankaj, country=India
Person List::id=2, name=Pankaj, country=India
Person List::id=3, name=Pankaj, country=India

Spring 4 Hibernate 4 통합 변경 사항

이제 Hibernate 3 대신 Hibernate 4를 사용하도록 애플리케이션을 변경해 보겠습니다. 이 마이그레이션의 경우 다음과 같은 구성 변경만 수행하면 됩니다.

  1. Change the hibernate version to 4.3.5.Final in the pom.xml file, as shown in comments above.

  2. Change the spring bean configuration file, till now you must have figured out that Spring bean configuration file is the key for integration of spring and hibernate framework. Below spring bean configuration file will work for Spring 4 and Hibernate 4 versions.

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="https://www.springframework.org/schema/beans"
    	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:aop="https://www.springframework.org/schema/aop"
    	xmlns:tx="https://www.springframework.org/schema/tx"
    	xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    		https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    		https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    		destroy-method="close">
    		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
    		<property name="url" value="jdbc:mysql://localhost:3306/TestDB" />
    		<property name="username" value="pankaj" />
    		<property name="password" value="pankaj123" />
    	</bean>
    
    
    <!-- Hibernate 4 SessionFactory Bean definition -->
    <bean id="hibernate4AnnotatedSessionFactory"
    		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    		<property name="annotatedClasses">
    			<list>
    				<value>com.journaldev.model.Person</value>
    			</list>
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    				<prop key="hibernate.current_session_context_class">thread</prop>
    				<prop key="hibernate.show_sql">false</prop>
    			</props>
    		</property>
    	</bean>
    
    	
    	<bean id="personDAO" class="com.journaldev.dao.PersonDAOImpl">
    		<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
    	</bean>
    </beans>
    

    For hibernate 4, we need to use org.springframework.orm.hibernate4.LocalSessionFactoryBean for SessionFactory bean, Spring ORM has merged both the classes for Hibernate 3 and there is a single class now, this is good to avoid confusion. All the other configurations are same as before.

그게 다야, 우리 프로젝트는 성공적으로 Hibernate 4로 마이그레이션되었습니다. Bean 구성에 spring4.xml을 사용하도록 SpringHibernateMain 클래스를 변경하면 제대로 작동하고 이전과 동일한 출력을 얻을 수 있습니다. 아래 링크에서 최종 프로젝트를 다운로드하고 더 많은 구성을 가지고 놀면서 자세히 알아볼 수 있습니다.

Spring Hibernate 통합 프로젝트 다운로드