11장. JPA 서브시스템

Name

Date

Reason For Changes

Version

오픈나루

2013/11

Initial Version

1.0

전준식, jjeon@opennaru.com

2018/02

Second Version

2.0

Java Persistence API(JPA)는 Java 오브젝트의 영속성(persistence)을 관리하기 위한 표준 API이다.

Hibernate EntityManager는 JPA 2.0 스펙에 정의된 프로그래밍 인터페이스 및 라이프 사이클 규칙을 구현한다. JBoss EAP 6의 JPA 구현체는 Hibernate EntityManager이다.

JBoss EAP 6는 JPA 2.0 표준을 완벽하게 준수하고 있다. 이번 장에서 JPA서브 시스템에 대해서 설명한다.

11-1.JPA란?

JPA는 객체와 RDBMS의 Entity를 변환하기 위한 API이다. 이미 Hibernate나 iBatis 등의 OR 맵핑이나 SQL 프레임워크를 사용하고 있다면 필요 없을 수도 있다.

하지만 JPA 표준을 주도한 인물이 JBoss Hibernate 프로젝트 창시자인 Gavin King이며, JPA가 Hibernate를 계승하고 있다는 점에서 주의 깊게 살펴보는 것이 좋다.

JBoss EAP 6에는 jboss.org에서 개발된 Hibernate 4.1이 포함되어 있다. Hibernate는 Java 애플리케이션 개발자가 Java 도메인 모델을 사용하여 RDBMS를 관리하기 위한 OR 맵핑 라이브러리와 툴을 제공한다. Hibernate 4.1의 EntityManager는 JPA 2.0로 정의된 프로그래밍 인터페이스와 라이프 사이클 관리 기능을 구현하고 있다. JPA 설정 파일에서 Hibernate 고유의 프로퍼티들도 설정할 수 있다.

11-2.OR 맵핑 프레임워크

Java 애플리케이션 개발 시 Java 및 데이터소스와의 통합에 대해서 쉽게 생각할 수도 있다. 하지만 단순한 데이터소스의 읽기, 쓰기 문제에 머물지 않고 다음과 같은 매우 복잡한 것들이 얽혀 있다.

Java에서 객체는 직접호출하면 되지만, RDBMS는 주 키와 외부 키를 사용하여 테이블간 조인을 통해 호출한다. 최대한 재사용하기 위해서 Java의 객체는 캡슐화를 사용한다. 이것을 관계형 데이터베이스로 맵핑하면 불필요한 호출이 많이 발생한다.

객체 모델과 관계형 모델 간의 맵핑이 어려워진다. 객체-관계 임피던스 불일치(Object-Relational Impedance Mismatch)란 객체지향 애플리케이션에서 객체와 RDBMS에 있는 테이블을 결합하는 과정에서 성능이 떨어지는 현상을 통칭하는 말이다. 임피던스 불일치(Impedance Mismatch)는 원래 불충분한 전력 흐름을 나타내는 전기공학 용어로부터 유래된 단어이다.

개발자는 애플리케이션 설계 및 데이터베이스 무결성에 영향을 주지 않고 객체 지향 Java 애플리케이션을 관계형 및 비 관계형 데이터 소스와 쉽게 통합하는 제품이 필요하다.

JPA는이런 맵핑을 유연하게 처리하여 객체지향 기술과 관계형 데이터베이스를 쉽게 연결해 주기 때문에 개발자가 빠르게 맵핑을 구현할 수 있도록 한다.

객체지향 애플리케이션과 관계형 데이터를 연결하는 미들웨어를 사용하여 복잡한 객체의 저장을 단순화하고 있다. 또, 객체지향과 관계형 데이터 사이에 있는 애플리케이션 서버에 위치하기 때문에 가장 빈번하게 호출되는 데이터를 캐시에 저장해 애플리케이션 성능을 빠르게 할 수 있다.

11-3.JPA주요 개념

JPA 관련 용어 설명

엔티티

엔티티는 데이터베이스 테이블에 연결되는 자바 빈이다. 엔티티는 POJO로 구현하고 어노테이션을 사용하여 연결할 데이터베이스 테이블 이름을 지정한다. 엔티티 작업을 위한 API는 엔티티 관리자가 제공한다.

엔티티 관리자

엔티티 관리자는 애플리케이션에 대한 CRUD 작업을 위한 인터페이스를 제공한다. 또 영속성 컨텍스트에서는 엔티티 상태를 관리하고 엔티티와 데이터베이스간의 동기화를 담당한다.

퍼시스턴스 컨텍스트

퍼시스턴스 컨텍스트는 엔티티 관리자가 관리하는 메모리상의 엔티티 집합이다. 엔티티 관리자는 컨텍스트에서 엔티티 개체와 라이프 사이클을 관리한다.

엔티티 관리자 팩토리

엔티티 관리자 팩토리는 엔티티 관리자를 생성하는 팩토리의 역할을 한다.

퍼시스턴스 유닛

퍼시스턴스 유닛은 엔티티 관리자 단위이다. 퍼시스턴스에 대한 구성 정보(엔티티 클래스, 데이터 소스 등)를 유지하는 저장소이다. XML 파일 (persistence.xml)에 정의한다.

퍼시스턴스 프로바이더

EJB 컨테이너나 애플리케이션에서 호출하여 엔티티 관리자 팩토리를 생성한다. JPA 엔진의 핵심 기능이다

JPQL

JPQL(Java Persistence Query Language)은 엔티티 및 엔티티를 쿼리하는 데 사용하는 SQL과 유사한 쿼리 언어이다. JPQL를 실행하기 위한 API는 엔티티 관리자가 제공하고 있다.

표 1 . JPA 관련 주요 용어

애플리케이션은 JPA를 사용해 RDBMS에 있는 테이블의 레코드를 Java 오브젝트 처럼 다룰 수 있다. 테이블 상의 레코드에 대응하는 자바 오브젝트를 엔티티라고 하며 이 엔티티들은 메모리상의 퍼시스턴스 컨텍스트(PersistenceContext)에서 관리한다.

데이터베이스 쿼리 결과로 생성되는 엔티티들은 퍼시스턴스 컨텍스트에 저장하여 유지된다. 엔티티의 생성이나 업데이트는 이 퍼시스턴스 컨텍스트에서 저장되어 트랜잭션 시점에 데이터베이스에 반영된다. 이처럼 퍼시스턴스 컨텍스트는 데이터베이스에 반영되기 전에는 캐쉬처럼 다루어지기 때문에 1차 캐시라고도 한다. 클러스터 환경에서 여러 대의 머신에서 퍼시스턴스 컨텍스트 간에 공유하는 캐시를 2차 캐시(2nd Level Cache)라고 한다.

11-4.퍼시스턴스 유닛 설정

JPA에서 퍼시스턴스 컨텍스트가 어떤 데이터베이스용 SQL을 생성해야 할지, 또 어떤 데이터소스를 사용할지 등을 어디엔가 설정해야 한다. 이를 퍼시스턴스 유닛이라는 단위로 관리하며 persistence.xml 파일에 설정한다.

persistence.xml 파일 내용

다음의 persistence.xml 파일에서는 <persistence-unit>에 지정된 ‘test’라는 이름의 퍼시스턴스 유닛이 데이터소스로 ‘java:jboss/datasource/testDS’를 사용하도록 설정된 것을 확인할 수 있다.

<properties>에서는 벤더 고유의 속성들을 지정할 수 있다. JBoss EAP 6에서는 Hibernate를 JPA 구현체로 사용하기 때문에 Hiberanate의 속성들을 지정하고 있다.

<xml version="1.0" encoding="UTF-8" >
<persistence version="2.0"
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_2_0.xsd">
  <persistence-unit name="test">
    <jta-data-source>java:jboss/datasources/testDS</jta-data-source>
    <properties>
      <property name="hibernate.hbm2ddl.auto" value="create-drop" />
      <property name="hibernate.show_sql" value="false" />
    </properties>
  </persistence-unit>
</persistence>

persistence.xml파일은 EAR이나 JAR 파일일 경우에는 META-INF/persistence.xml에 저장하고, WAR파일에 포함할 경우에는 WEB-INF/classes/META-INF/persistence.xml에 저장하면 된다.

Hibernate 설정

JBoss EAP 6에서 JPA 구현체로 Hibernate를 사용하기 때문에 <properties>에서 Hibernate 속성을 지정할 수 있다고 했다. Hibernate에는 수많은 속성을 사용할 수 있지만, 주로 많이 사용되는 몇 가지 속성들에 대해서 간략히 설명한다. Hibernate에 대한 더 자세한 속성들은 매뉴얼을 참조하라.

속성 설명

hibernate.dialect

Hibernate에서 특정 데이터베이스에 대한 최적화된 SQL을 생성할 수 있도록 설정하는 값. 오라클 데이터베이스의 경우 ‘org.hibernate.dialect.Oracle10gDialect’이나 ‘org.hibernate.dialect.Oracle9iDialect’ 를 설정하고, MySQL일 경우에는 ‘org.hibernate.dialect.MySQL5Dialect’을 설정한다.

hibernate.show_sql

true로 설정하면 실행하는 SQL문을 로그에 출력한다.

hibernate.format_sql

true로 설정하면 로그에 SQL문을 포맷팅하여 출력한다.

hibernate.default_schema

SQL문에서 기본값으로 사용할 스키마를 지정한다.

hibernate.default_catalog

SQL문에서 기본값으로 사용할 카탈로그를 지정한다.

hibernate.generate_statistics

true로 설정하면 Hibernate의 통계정보를 수집한다. 수집된 값들은 JMX를 사용하여 확인할 수 있다. JMX 값을 확인하려면 JConsole을 사용한다.

hibernate.use_sql_comments

true로 설정하면 Hibernate가 생성하는 SQL문에 주석이 추가되어 디버깅시 사용할 수 있다.

hibernate.hbm2ddl.auto

개발시 사용하는 속성으로 처음 시작될 때 데이터베이스 스키마를 검증하여 스키마가 없으면 자동으로 생성하고, 종료될 때 스키마를 drop한다. 사용할 수 있는 옵션은 다음과 같다. ‘validate’ : 스키마를 검증한다. ‘update’ : 스키마를 갱신한다. ‘create’ : 스키마를 생성한다. ‘create-drop’ : 스키마를 생성하고 마지막에 삭제한다.

hibernate.hbm2ddl.import_files

개발시 사용하는 속성으로 스키마가 생성된 후 실행할 SQL문이 보관된 파일을 지정할 수 있다. 여러 파일을 지정하려면 컴마로 구분한다. hibernate.hbm2ddl.auto가 create나 create-drop으로 설정되어 있을 때만 실행된다.

표 2 . Hibernate 설정 항목

11-5.기본 JPA 데이터 소스 설정

JBoss EAP의 JPA 서브 시스템 설정은 persistence.xml 파일에서 데이터소스를 설정하지 않았을 경우에 기본값으로 사용할 수 있도록 기본 데이터소스를 설정하는 것이 있다. 기본값은 설정되어 있지 않다.

관리 콘솔에서 ‘Profile’ → ‘Container’ → ‘JPA’에서 설정할 수 있다.

image

그림 1. JPA 서브시스템 설정

CLI에서는 /subsystem=jpa에서 다음과 같이 default-datasource 설정을 할 수 있다.

[standalone@localhost:9999 subsystem=jpa] :write-attribute(name=default-datasource, value=java:jboss/datasources/testDS)
{"outcome" => "success"}