제2장 프로바이더 설정

내용 목차

2.1. 데이터베이스 설정
2.1.1. 사용 환경별 설정
2.1.2. 데이터베이스 타입 설정
2.1.3. 스키마 자동 생성 설정
2.2. Caching
2.3. Query 힌트
2.4. Logging 설정

본 장에서는 JEUS의 기본 프로바이더인 EclipseLink에 대한 설정을 설명한다. 이러한 설정은 JPA 스펙에서 정의되지 않는 기능을 구현하기 위해 필요한 부분으로, 각 애플리케이션에 맞게 정확하게 설정되어야 한다.

2.1. 데이터베이스 설정

사용 환경, 데이터베이스 타입에 따른 설정과 자동으로 데이터베이스 스키마를 생성하는 설정에 대해 설명한다.

2.1.1. 사용 환경별 설정

사용 환경에 따라 데이터베이스의 설정 방법이 달라진다.

Java EE 환경

Java EE 환경(또는 모드)은 JEUS의 Managed Server(이하 MS) 위에서 웹 컨테이너, EJB 컨테이너, 애플리케이션 클라이언트 컨테이너를 의미한다.

참고

좀 더 정확하게는 각 컨테이너에서 컨트롤하는 Thread를 의미한다. 예를 들어 웹 엔진에 설정하는 Web Thread Pool의 Thread이다. 만약 애플리케이션이 직접 생성한 Thread Pool의 Thread처럼 컨테이너가 관리하지 않는 Thread 상에서는 Java SE 환경과 똑같다.

사용할 데이터베이스 대상에 대한 설정은 persistence.xml Descriptor에 설정한다. 사용할 트랜잭션의 종류에 따라서 <jta-data-source>와 <non-jta-data-source> 값을 설정한다.

  • 글로벌 트랜잭션을 사용하는 경우

    • <transaction-type>의 값을 'JTA'로 설정한다.

    • <jta-data-source>에 해당 데이터소스의 JNDI 이름을 설정한다.

  • 로컬 트랜잭션을 사용하는 경우

    • <transaction-type>의 값을 'RESOURCE_LOCAL'로 설정한다.

    • <non-jta-data-source>에 해당 데이터소스의 JNDI 이름을 설정한다.

[예 2.1] Java EE 모드에서 데이터베이스 설정 예

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="em" transaction-type="JTA">
    <jta-data-source>jdbc/MyDB</jta-data-source>
  </persistence-unit>
</persistence>


참고

1. Java EE 환경에서는 <transaction-type> 값을 지정하지 않을 경우 기본적으로 JTA 트랜잭션으로 설정한다.

2. JEUS에서 DB 데이터소스를 설정하는 방법은 JEUS Server 안내서”의 “제6장 DB Connection Pool과 JDBC”를 참고한다.

Java SE 환경

Java SE 환경(또는 모드)은 Java EE 컨테이너에서 사용하지 않고 Java Standalone 클라이언트와 같은 환경에서 사용하는 경우를 말한다. 이때는 로컬 트랜잭션만 사용할 수 있으며, 사용되는 데이터베이스의 JDBC 설정을 프로퍼티로 설정해야 한다.

다음의 예제와 같이 <transaction-type>의 값을 'RESOURCE_LOCAL'로 설정한다.

[예 2.2] Java SE 모드에서 데이터베이스 설정 예

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="em" transaction-type="RESOURCE_LOCAL">
    <properties>
      <property name="eclipselink.jdbc.driver"
                value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="eclipselink.jdbc.url"
                value="jdbc:derby://localhost:1527/testdb"/>
      <property name="eclipselink.jdbc.user" value="APP"/>
      <property name="eclipselink.jdbc.password" value="APP"/>
    </properties>
  </persistence-unit>
</persistence>


다음은 프로퍼티 값에 대한 설명이다.

[표 2.1] Java SE 모드 데이터베이스 프로퍼티

프로퍼티 값설명
eclipselink.jdbc.driver대상 데이터베이스의 JDBC 드라이버 클래스 이름이다.
eclipselink.jdbc.url대상 데이터베이스의 JDBC URL이다.
eclipselink.jdbc.user대상 데이터베이스의 사용자명이다.
eclipselink.jdbc.password대상 데이터베이스의 패스워드이다.

2.1.2. 데이터베이스 타입 설정

기본적으로 해당 데이터베이스 타입을 JDBC 커넥션 정보를 통해 자동으로 감지한다. 자동 감지 기능이 제대로 동작하지 않거나, 별도의 다른 데이터베이스를 사용하는 경우라면 'eclipselink.target-database' 프로퍼티를 설정할 수 있다.

참고

데이터베이스 타입은 JDBC 드라이버의 DatabaseMetaData.getDatabaseProductName()을 사용하여, 데이터베이스 벤더 이름을 regular expression으로 비교하는 방식을 사용한다.

[예 2.3] 데이터베이스 타입 설정 예

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="em">
    <jta-data-source>jdbc/MyDB</jta-data-source>
    <properties>
      <property name="eclipselink.target-database" value="DB2"/>
    </properties>
  </persistence-unit>
</persistence>

다음은 지원되는 데이터베이스 타입 값에 대한 설명이다.

[표 2.2] eclipselink.target-database 프로퍼티

설명
Auto자동 감지(기본값)
AttunityAttunity DBMS
CloudscapeCloudscape DBMS
DB2IBM DB2 DBMS
DB2MainframeIBM DB2 Mainframe DBMS
DBaseDBase DBMS
DerbyApache Derby DBMS
HSQLHSQL DBMS
InformixInformix DBMS
JavaDBJavaDB DBMS
MySQL4MySQL DBMS
OracleOracle DBMS
PointBasePointBase DBMS
PostreSQLPostreSQL DBMS
SQLAnyWhereSQLAnywhere DBMS
SQLServerMicrosoft SQLServer DBMS
SybaseSybase DBMS
TimesTenOracle Timesten DBMS
Customized class name기본적으로 지원되지 않는 DBMS를 추가할 때 사용한다.

기본적으로 지원되지 않는 DBMS의 경우 별도로 DBMS 지원 기능을 구현하여 사용할 수 있다. 이때는 해당 클래스 이름을 지정한다. 이에 대한 자세한 내용은 본 안내서의 참고 자료를 참고한다.

2.1.3. 스키마 자동 생성 설정

자동으로 DB 스키마를 생성하는 기능을 사용하는 경우 설정한다. 이를 사용하면 애플리케이션을 deploy할 때 DB 테이블 및 제약 사항(Constraints)을 자동으로 생성한다.

[예 2.4] 스키마 자동 생성 설정 예

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="em">
    <jta-data-source>jdbc/MyDB</jta-data-source>
    <properties>
      ...
      <property name="eclipselink.ddl-generation" value="create-tables" /> 
      ...
    </properties>
  </persistence-unit>
</persistence>

관련된 프로퍼티 설정은 다음과 같다.

항목설명
eclipselink.ddl-generation

스키마 DDL(Data Descriptor Language)을 어떤식으로 생성할지 설정한다.

  • none : 아무것도 하지 않는다. (기본값)

  • create-tables : 존재하지 않는 테이블을 생성하며, 기존 테이블은 그대로 남겨둔다.

  • drop-and-create-tables : 기존에 존재하는 테이블을 삭제하고 다시 생성한다.

DDL을 생성할 때 기본적으로 다음과 같이 Java 타입을 해당 데이터베이스 SQL 타입에 맞게 생성한다.

[표 2.3] Java Type to SQL Type Mappings

Java TypeDerby, JavaDB, CloudscapeOracleDB2SybaseSQLServerMySQL
boolean, BooleanSMALLINTNUMBER(1)SMALLINTBITBITTINYINT(1)
int, IntegerINTEGERNUMBER(10)INTEGERINTEGERINTEGERINTEGER
long, LongBIGINTNUMBER(19)INTEGERNUMERIC(19)NUMERIC(19)BIGINT
float, FloatFLOATNUMERIC(19,4)FLOATFLOAT(16)FLOAT(16)FLOAT
double, DoubleFLOATNUMERIC(19,4)FLOATFLOAT(32)FLOAT(32)DOUBLE
short, ShortSMALLINTNUMBER(5)SMALLINTSMALLINTSMALLINTSMALLINT
byte, ByteSMALLINTNUMBER(3)SMALLINTSMALLINTSMALLINTSMALLINT
java.lang.NumberDECIMALNUMBER(38)DECIMAL(15)NUMERIC(38)NUMERIC(28)DECIMAL(38)
java.math.BigIntegerBIGINTNUMBER(38)BIGINTNUMERIC(38)NUMERIC(28)BIGINT
java.math.BigDecimalDECIMALNUMBER(38)DECIMAL(15)NUMERIC(38)NUMERIC(28)DECIMAL(38)
java.lang.StringVARCHAR(255)VARCHAR(255)VARCHAR(255)VARCHAR(255)VARCHAR(255)VARCHAR(255)
char, CharacterCHAR(1)CHAR(1)CHAR(1)CHAR(1)CHAR(1)CHAR(1)
byte[], Byte[], java.sql.BlobBLOB(64000)LONG RAWBLOB(64000)TEXTTEXTTEXT(64000)
char[], Character[], java.sql.ClobCLOB(64000)LONGCLOB(64000)TEXTTEXTTEXT(64000)
java.sql.DateDATEDATEDATEDATETIMEDATETIMEDATE
java.sql.TimeTIMEDATETIMEDATETIMEDATETIMETIME
java.sql.TimestampTIMESTAMPDATETIMESTAMPDATETIMEDATETIMEDATETIME


2.2. Caching

JPA에서는 기본적으로 Persistence Context라고 하는 1st-level Caching을 지원하고 있다. 하지만, 일반적으로 Persistence Context는 트랜잭션별로 새로 생성되기 때문에(Extended Persistence Context는 이에 해당하지 않음) 트랜잭션 간에 Caching을 지원하지 않는다. 이를 보완하기 위해 TopLink Essentials에서는 2nd-level Caching 기능을 제공한다.

2nd-level Caching은 EntityManagerFactory 레벨에서 지원되기 때문에, 동일한 EntityManagerFactory에서 생성된 모든 EntityManager의 경우 이 공유 Cache를 사용하게 된다. 즉, Persistence Context에 없는 Entity를 가져올 때 2nd-level Caching을 참고하여 존재하는 경우에 이를 가져온다. 따라서 반복적인 Read 작업의 경우 성능 향상을 가져오게 된다.

[예 2.5] Caching 방식 설정 예

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="em">
    <jta-data-source>jdbc/MyDB</jta-data-source>
    <properties>
      ...
      <property name="eclipselink.ddl-generation" value="create-tables" />
      <property name="eclipselink.cache.type.default" value="NONE" />
      <property name="eclipselink.cache.size.default" value="999" />
      <property name="eclipselink.cache.shared.default" value="false" /> 
      ...
    </properties>
  </persistence-unit>
</persistence>

다음은 Caching에 관련된 옵션에 대한 설명이다.

항목설명
eclipselink.cache.type.default

Caching 방식을 설정한다.

  • Full : 객체를 Hard reference로 caching한다. 따라서 Entity가 삭제되기 전까지 항상 Cache에 존재하게 된다.

  • HardWeak : Weak와 유사하며, 자주 사용되는 객체는 Hard reference로 caching한다.

  • SoftWeak : Weak와 유사하며, 자주 사용되는 객체는 Soft reference로 caching한다. 자주 사용되는 객체는 메모리가 부족할 때 사라진다. (기본값)

  • Weak : 객체를 Weak reference로 caching한다. Garbage Collection(GC)이 되면 사라진다.

  • NONE : 객체를 Cache에 저장하지 않는다. 사용을 권장하지 않으며 Caching 기능을 사용하고 싶지 않다면, toplink.cache.shared.xxx 프로퍼티를 설정하기를 권장한다.

eclipselink.cache.size.defaultCache에 저장될 최대 객체수를 설정한다. (기본값 : 1000)
eclipselink.cache.shared.default

공유 Cache를 사용할지 여부를 설정한다.

  • true : 객체가 공유 Cache에 저장된다. 모든 EntityManager는 Caching을 사용하게 된다. (기본값)

  • false : 객체가 공유 Cache에 저장되지 않는다. 따라서, EntityManager별로 Cache를 공유하지 않는다. 이를 사용하면 2nd-level Caching을 하지 않는 효과가 있다.

eclipselink.cache.type.<ENTITY>

Entity별로 Caching을 하는 방식을 지정한다.

<ENTITY>는 Entity 이름 또는 fully-qualified 클래스 이름이 될 수 있다. 해당 Entity와 관계를 가지는 모든 Entity는 같은 설정을 가져야 한다.

eclipselink.cache.type.default의 값 설명과 동일하다.

eclipselink.cache.size.<ENTITY>

Entity별로 Cache 사이즈를 지정한다.

<ENTITY>는 Entity 이름 또는 fully-qualified 클래스 이름이 될 수 있다.

eclipselink.cache.size.default의 값 설명과 동일하다.

eclipselink.cache.shared.<ENTITY>

Entity별로 공유 Cache를 사용할지를 지정한다.

<ENTITY>는 Entity 이름 또는 fully-qualified 클래스 이름이 될 수 있다. 해당 Entity와 관계를 가지는 모든 Entity는 동일한 설정을 가져야 한다.

eclipselink.cache.shared.default의 값 설명과 동일하다.

주의

2nd-level Caching이 사용될 때 주의할 것은 외부 애플리케이션에 의해 또는 직접 데이터베이스의 데이터를 변경하는 경우 해당 내용이 Caching에 반영되지 않는다는 점이다. 이런 경우 데이터베이스의 최신 값이 아닌 Caching된 값이 리턴되기 때문에 애플리케이션에 이를 고려해야 한다.

Caching 옵션을 애플리케이션 환경을 고려하여 적절히 설정하거나, EntityManager.refresh(), eclipselink.refresh Query 힌트 또는 locking(pessimistic/optimistic) 등을 사용하여 이런 문제를 피할 수 있다.

2.3. Query 힌트

Query 힌트는 Query 객체를 사용할 때 프로바이더에서 제공하는 기능을 사용하도록 한다.

다음 예제와 같이 Query를 실행할 때 설정할 수도 있고, Named Query를 사용하는 경우 @QueryHint Annotation을 사용하여 지정할 수도 있다.

[예 2.6] Query 힌트 사용 예제

List employees 
  = em.createQuery("SELECT e FROM Employee e WHERE e.name = :name")
      .setParameter("name", name)
      .setHint("eclipselink.refresh", true)
      .getResultList();


제공하는 Query 힌트는 다음과 같다.

항목설명
eclipselink.pessimistic-lock

SELECT할 때 Pessimistic Locking을 사용할지 여부를 설정한다.

  • NoLock : 사용하지 않는다. (기본값)

  • Lock : SELECT ... FOR UPDATE 문을 사용해 Locking을 한다.

  • NoLockWait : SELECT ... FOR UPDATE NO WAIT 문을 사용해 Locking을 한다.

eclipselink.refresh

데이터베이스에서 최신 값을 가져와 Caching을 업데이트할지 여부를 설정한다.

  • true : 최신 값을 가져오고 Caching을 업데이트한다.

  • false : Cache에 있는 값을 사용한다. (기본값)

2.4. Logging 설정

좀 더 자세한 로그를 보고 싶다면 Logging 레벨을 설정할 수 있다.

기본적으로 Logging 레벨은 JEUS 서버에 전체적으로 적용되는 레벨(기본적으로 INFO)을 따르게 되지만, 이를 Persistence Unit별로 변경할 경우 eclipselink.logging.level 프로퍼티로 설정할 수 있다.

Logger의 경우 Java EE 모드에서는 기본적으로 JEUS에서 제공되는 Logger(JEUS Logger)를 사용하게 되며, Java SE 모드에서는 standard output으로 출력되는 DefaultLogger를 사용하게 된다. 이를 변경하려면 eclipselink.logging.logger 프로퍼티로 설정할 수 있다.

[예 2.7] Logging 설정 예

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="em">
    <jta-data-source>jdbc/MyDB</jta-data-source>
    <properties>
      ...
      <property name="eclipselink.logging.level" value="FINE"/>
      <property name="eclipselink.logging.logger" value="DefaultLogger"/>
      ...
    </properties>
  </persistence-unit>
</persistence>

다음은 설정에 대한 자세한 설명이다.

항목설명
eclipselink.logging.level

Logging 레벨을 지정한다.

  • OFF : Logging을 하지 않는다.

  • SEVERE

  • WARNING

  • INFO (기본값)

  • CONFIG

  • FINE : SQL 관련 정보를 조회하려면 이 레벨로 설정한다.

  • FINER

  • FINEST

eclipselink.logging.logger

사용할 Logger를 지정한다.

  • JEUSLogger : JEUS에서 제공되는 Logger이다.

    (Java EE 모드인 경우 기본값)

  • DefaultLogger : 기본 standard output Logger이다.

    (Java SE 모드인 경우 기본값)

  • JavaLogger : java.util.logging Logger이다.

  • Custom class name : 별도의 Logger를 구현한 경우 지정한다.

참고

1. EclipseLink에 대한 자세한 설정은 http://wiki.eclipse.org/EclipseLink/UserGuide/JPA를 참고한다.

2. TopLink에서 EclipseLink로 전환할 경우 http://www.eclipse.org/eclipselink/documentation/2.4/solutions/migrnativetoplink.htm를 참고한다.