이 FAQ 문서는 업계에서 가장 진보된 O/R(object-to-relational) 아키텍처인 TopLink에 관련하여
자주 질문되는 사항에 대한 설명을 담고 있습니다. TopLink는 Java 오브젝트와 Enterprise Java Beans(EJB)를
관계형 데이터베이스의 테이블에 저장하기 위한 유연하고 생산적인 메커니즘을 제공합니다. TopLink는 개발자에게 매우 뛰어난
성능과 넓은 선택의 폭을 제공하며, 다양한 데이터베이스, 애플리케이션, 개발 툴셋 및 프로세스, J2EE 아키텍처와 호환합니다.
TopLink는 업계에서 가장 진보된 O/R(object-to-relational) 프레임워크입니다. TopLink는
Java 오브젝트와 Enterprise Java Beans(EJB)를 관계형 데이터베이스의 테이블에 저장하기 위한
유연하고 생산적인 메커니즘을 제공합니다. TopLink는 개발자에게 매우 뛰어난 성능과 넓은 선택의 폭을 제공하며,
아래와 같은 환경적 요소로부터 독립적입니다:
데이터베이스
애플리케이션 서버
개발 툴셋 및 프로세스
J2EE 아키텍처
새로운 10.1.3 Release에서는, 오브젝트를 XML 문서 또는 레거시 시스템으로 매핑하는 기능이 추가되었습니다.
이 기능은 OTN의 TopLink 10g Release 2 (10.1.3)
Developer Preview를 다운로드하여 확인하실 수 있습니다.
TopLink의
가격은 얼마나 됩니까? 라이센스는 어떻게 관리됩니까?
OTN 라이센스 정책에 의거, 개발 및 평가를 위한 목적으로 사용하는 경우 TopLink를 무료로 다운로드하여
사용하실 수 있습니다. 운영환경을 위한 라이센스는 OracleAS의 모든 에디션에 기본 포함되어 있으며 CPU당 $5,000의
가격으로 별도 구매하실 수도 있습니다.
TopLink는 애플리케이션입니까, 아니면
EJB 서버입니까?
TopLink는 애플리케이션도, EJB 서버도 아니며, 순수 Java 클래스 라이브러리로 보는 것이 정확합니다.
TopLink는 100% 검증된 Pure Java로서 구현되므로, 인증된 Java 환경이라면 어디서든 실행이 가능합니다.
TopLink는 엔터프라이즈 환경의 애플리케이션 및 EJB 서버와도 통합되어 있습니다. TopLink는 Oracle
Application Server Containers for J2EE (OC4J), IBM WebSphere, BEA
WebLogic 등의 Entity Beans를 위한 CMP(container-managed beans)를 함께 제공하고
있습니다.
개발 툴: TopLink Mapping Workbench, TopLink Sessions Editor
런타임 툴: Web Client
TopLink는 어떤 Java
타입을 지원합니까?
FTopLink는 데이터베이스 데이터타입과 다음 Java 타입 간의 자동 변환을 지원합니다:
String, Number, BigDecimal, BigInteger, Long, long, Integer, int,
Float, float, Double, double, Byte, byte, Short, short, java.util.Date,
java.sql.Date, Time, Timestamp, Calendar, byte[], Boolean, boolean다른
Java 타입의 경우 오브젝트 타입, 타입 변환, 또는 변환 매핑을 사용하거나 “direct-to-field” get/set
메소드의 값을 변환해 주어야 합니다.
TopLink는 Oracle, IBM Universal Database, IBM Informix, IBM Cloudscape,
Microsoft SQL Server, Microsoft Access, Sybase Adaptive Server 등
JDBC 호환 드라이버를 제공하는 모든 관계형 데이터베이스를 지원합니다. TopLink는 JDBC 1.x 및 2.0
표준을 지원합니다.
TopLink는 어떤
Java 오브젝트를 지원합니까 (예: Java Object, EJB, JavaBeans)?
TopLink는 POJO(Plain Old Java Object), Java Beans를 위한 퍼시스턴스, 모든
종류의 애플맄이션 서버를 위한 EJB BMP(bean managed persistence), Oracle Application
Server Containers for J2EE (OC4J), IBM WebSphere, BEA WebLogic의
Entity Bean을 위한 CMP(container-managed persistence)를 지원합니다.
TopLink는 어떤
아키텍처를 지원합니까 (예: J2EE, EJB, JSP)?
TopLink는 아키텍처 중립적인 제품입니다. TopLink는 특정 아키텍처를 요구하지 않으며, J2SE, J2EE,
EJB, JSP, Struts 등을 이용하는 수천 여종의 애플리케이션에서 사용되고 있습니다.
내가 사용하는 애플리케이션
서버에서 TopLink Foundation Library를 이용할 수 있습니까?
TopLink Foundation Library는 Java Virtual Machine(JVM)에서 실행되는 모든
애플리케이션 서버를 지원합니다. 일반 Java 오브젝트를 사용하거나 BMP(bean-managed persistence)
Entity Beans와 통합할 수도 있습니다. 또 TopLink를 Oracle Application Server
Containers for J2EE (OC4J), BEA WebLogic, IBM WebSphere 애플리케이션 서버에서
사용하고자 하는 경우에는 TopLink CMP(container-managed persistence) Foundation
Library가 필요합니다.
EJB 2.x, 3.0 환경에서도
TopLink가 필요합니까?
그렇습니다. EJB 2.x 및 3.0 표준안은 Entity Beans를 위한 두 종류의 퍼시스턴스 메커니즘, 즉
CMP(container-managed persistence)와 BMP(bean-managed persistence)를
정의하고 있습니다. 하지만 표준안은 구체적인 구현방법에 대해서는 설명하고 있지 않습니다. TopLink는 Oracle
Application Server Containers for J2EE (OC4J), BEA WebLogic, IBM
WebSphere 애플리케이션 서버를 위한 CMP를 구현하고 있습니다. 또 다른 EJB 서버의 BMP 구현을 위해
TopLink를 사용할 수도 있습니다.
TopLink는
멀티쓰레드 환경에서 동작합니까?
TopLink는 100% “thread safe”하게 동작하며, thread safety를 요구하는 JSP/Servlet
또는 EJB 애플리케이션에서 사용 가능합니다.
데모는 어디에서 확인할 수 있습니까?
OTN의 TopLink
데모 페이지에서 데모를 확인하실 수 있습니다. 또 OTN의 TopLink
페이지에서 다운로드 가능한 TopLink 배포판에 다양한 실행 예제가 포함되어 있습니다.
TopLink 사용자 포럼은 어디에 있습니까?
OTN의 TopLink
포럼은 TopLink 사용자와 TopLink 엔지니어링 팀원들이 매우 활발하게 정보를 교환하는 장으로 활용되고
있습니다.
TopLink에는 매핑을 위한 GUI가 지원됩니까?
이 GUI를 반드시 사용해야 하나요?
TopLink는 매핑 툴을 제공하고 있습니다. 하지만 반드시 이 툴을 사용할 필요는 없습니다. 매핑 툴은 JDeveloper에
통합되어 있으며, 스탠드얼론 형태의 Mapping Workbench를 통해서도 사용이 가능합니다. 이 툴은 XML
deployment descriptor 파일을 직접 편집하거나, TopLink Foundation Library API를
이용해서 직접 코딩을 수행하는 것보다 훨씬 뛰어난 생산성을 제공합니다. TopLink 매핑 툴은 매핑에 존재하는 문제를
자동으로 확인해 주무로, 에러를 확인하기 위해 시행착오를 거칠 필요가 없습니다. 수백 개의 XML 매핑 파일이 존재하는
대규모 프로젝트에서 매핑 상의 문제를 점검하는 것은 결코 간단한 문제가 아닙니다. TopLink 매핑 툴을 이용해서
O/R 매핑을 효율적으로 관리할 수 있습니다.
TopLink는 오브젝트 퍼시스턴스를
위한 코드를 생성해 주나요?
TopLink는 메타데이터 아키텍처를 사용하므로, 애플리케이션 퍼시스턴스를 구현하기 위해 별도의 코드를 생성할 필요가
없습니다.
TopLink에 의해 생성되는 내역이 다음과 같습니다:
TopLink 프로젝트와 관련 descriptor를 단일 Java 클래스에 생성합니다. 이 클래스를 컴파일하고
런타임 deployment XML 파일 대신 사용할 수 있습니다.
테이블 생성을 위한 Java 클래스를 생성합니다. 이 클래스를 컴파일하고, 데이터베이스에 필요한 제약조건을
갖는 모든 테이블을 일괄적으로 생성할 수 있습니다.
프로젝트에 정의된 클래스를 위한 소스 코드를 생성합니다.
기존 데이터베이스 스키마로부터 Java 오브젝트 모델, EJB-CMP EntityBean 모델, EJB-BMP
EntityBean 모델을 생성합니다.
TopLink는 EJB2.0 CMP를 위한 클래스를 생성합니다.
17. TopLink를
사용하기 위해 특수한 형태의 서브클래스 또는 인터페이스를 구현해야 하나요?
TopLink는 개발자에게 특수한 서브클래스 또는 인터페이스의 구현을 요구하지 않습니다. TopLink와의 종속성을
갖지 않는 도메인 모델을 생성하고 퍼시스턴스를 갖는 맵의 생성에 이용할 수 있습니다.
TopLink의 설계담당자 마이크 키스(Mike Keith)는 이 질문에 대해 이렇게 답변합니다:
TopLink는 reflection을 적극적으로 활용하고 있습니다. 우리는 reflection artifact의
캐싱이 가능한 한, reflection 기반 아키텍처가, non-reflection 기반 제품에 비해 결코 성능이
떨어지지 않음을 주장해 왔습니다. 우리의 이러한 주장은 사실임이 입증되었고, 다른 제품의 사례를 통해서도 확인이 되었습니다.
실제로 간단한 벤치마크를 통해서도 reflective 메소드 호출과 필드 액세스에서 유사한 결과를 얻을 수 있음을
확인할 수 있습니다.
TopLink는 애플리케이션이 SOA 환경에서 유연하게 개발, 수정될 수 있는 환경을 제공합니다. 애플리케이션과
퍼시스턴트 데이터 간의 느슨한 커플링(loose coupling)을 통해, TopLink는 개발자들이 그리드 환경에
맞게끔 애플리케이션을 최적화할 수 있게 합니다. 또, TopLink는 애플리케이션 및 기타 오라클 개발 프레임워크에서
사용되는 핵심적인 퍼시스턴스 기능을 제공하고 잇습니다.
TopLink는 JDO (JSR-012) 표준안과
호환합니까?
호환되지 않습니다. TopLink는 JDO 1.0 표준안을 완전히 구현하고 있지 않습니다. JDO API의 일부가
TopLink 9.0.4에서 지원되고 있긴 하지만, 이 API는 10.1.3에서 공식적으로 사용되지 않으며 이후 버전에서
삭제될 것입니다.
TopLink를 설치한 후, 개발 시스템이 TopLink 클래스를 사용하도록 설정하고 TopLink가 코어 Java
클래스, JVM(Java Virtual Machine), 도메인 클래스에 접근할 수 있도록 허용해 주어야 합니다.
자세한 정보는 TopLink OracleAS Getting Started Guide와 MetaLink
Knowledge Base에서 확인하실 수 있습니다. 중요한 정보만 간단하게 요약하면 다음과 같습니다.
올바른 JVM이 classpath에 존재함을 확인합니다.
TopLink Foundation 클래스(toplink.jar)가 classpath에 존재함을 확인합니다.
TopLink를 이용해 매핑할 모든 도메인 클래스가 classpath에 존재함을 확인합니다.
JDBC 드라이버 클래스의 경로가 classpath에 존재함을 확인합니다.
그 밖에 TopLink CMP(container-managed
persistence) Foundation Library가 제공하는 기능으로 어떤 것이 있습니까?
TopLink CMP Foundation Library는 TopLink Foundation Library를 포함하고
있으며, 따라서 TopLink Foundation Library와 동일한 기능이 사용 가능합니다. 이에 더하여, 이
라이브러리를 이용하여 BEA WebLogic 및 IBM WebSphere 애플리케이션 서버의 CMP Entity Beans와
TopLink를 연동할 수 있습니다.
TopLink는 direct 또는 reference relationship을 위한 포괄적인 매핑 셋을 제공합니다.
개발자는 TopLink를 이용함으로써, 두 모델 간의 관계를 별도로 기술하지 않고도 오브젝트 모델과 관계형 모델을
매핑할 수 있습니다.
Direct Mappings
Direct To Field
Object Type
Type Conversion
Serialized Object
Direct To XML
Direct Collection
Direct Map
Transformation
Relationship Mappings
Aggregate Object
One To One
Variable One To One
One To Many
Many To Many
Direct Collection
Aggregate Collection
Object-relational Mappings
Structure
Reference
Nested Table
Array
Object Array
TopLink로 private
field 또는protected field를 매핑할 수 있습니까?
TopLink를 이용하여 공개되지 않은 필드, 메소드에 접근하는 것이 가능합니다. TopLink에 ReflectPermission
권한이 부여된 경우, reflect된 member와 constructor를 이용하면서 디폴트 Java 언어 액세스
컨트롤을 비활성화할 수 있습니다. 또 보안 정책 파일(security policy file)은 정책 툴 애플리케이션
사용 권한을 설정하는데 이용됩니다.
NULL을
허용하는 컬럼을 Java 타입으로 매핑할 수 있습니까?
일반적으로는 불가능합니다. Java가 지원하는 프리미티브 타입(primitive type)은 null 값을 허용하지
않습니다. 필드값이 null이거나 TopLink가 프리미티브 타입에 null을 할당하려 시도하는 경우, Java는
NullPointerException을 발생시킵니다. 이 문제를 피하는 가장 간단한 방법은 프리미티브 타입에 대응되는
모든 데이터베이스 필드에서 null을 허용하지 않는 것입니다. TopLink Mapping Workbench에서 모든
direct mapping에 대해 NullValue 속성을 적용하고 null 값에 대한 디폴트 값을 매핑시키도록 설정하는
것도 한 가지 방법입니다. 이와 같이 하려면 아래와 같은 코드를 사용하면 됩니다:
mapping.setNullValue(new Integer(0));
또, OracleAS TopLink Mapping Workbench를 이용하여 DatabaseLogin의 모든 매핑
및 descriptor에 대해 NullValue를 설정해 주어야 합니다. 그 방법이 아래와 같습니다:
login.setDefaultNullValue(int.class, new Integer(0));
TopLink는
클래스가 아닌, 인터페이스에 대한 관계 매핑을 지원합니까?
네, 지원합니다. 클래스가 아닌 인터페이스를 참조하는 매핑을 정의하는 것도 가능합니다. TopLink는 이를 변수
클래스 매핑(variable class mapping)이라 부릅니다. 단일 클래스, 또는 다수의 implementor에
대해 인터페이스를 정의할 수 있습니다. 이때 인터페이스에 대한 쿼리를 수행하면, 각각의 implementor 별로
쿼리가 실행됩니다.
TopLink에서 1:1 변수 클래스
매핑을 정의하려면 어떻게 해야 합니까?
TopLink는 1:1 변수 매핑을 지원합니다. 1:1 변수 매핑(variable mapping)이란 소스 오브젝트가
하나 또는 그 이상의 비상속 클래스(non-inherited class)를 참조하는 경우를 의미합니다. 이때 매핑의
타겟 클래스는 인터페이스를 통해 연결되어야 합니다.또 인터페이스를 위한 interface descriptor를 정의해야
하며, 타겟 클래스는 해당 인터페이스를 구현하고 있어야 합니다.
매핑의 선택 기준은 타겟 인터페이스의 쿼리 키(query key)를 이용하여 정의되며, 소스 오브젝트 테이블의 타입
필드는 참조되는 오브젝트의 타입 정보를 저장하게 됩니다.
관계 매핑이 “privately
owned”로 표시되는 것은 무슨 의미입니까?
TopLink에서 모든 종류의 레퍼런스 매핑(1:1, 1:M, M:M)에 대해 “privately owned”로
설정할 수 있습니다. 이는 소스 오브젝트가 삭제되는 경우, 소스 오브젝트의 “privately owned” 구성요소가
함께 삭제됨을 의미합니다.
하나의 컬럼에 대해
여러 개의 매핑을 설정할 수 있습니까?
네, 가능합니다. 단, 매핑 중 하나만이 “writeable”로 설정되어 있어야 합니다. TopLink는 데이터베이스
로우를 구성하는 과정에서 오브젝트로부터 값을 가져오기 위한 “writeable” 매핑을 기본적으로 요구합니다. 특정
매핑을 읽기 전용으로 설정할 수도 있으며, 1:1 매핑의 경우에는 타겟 외래 키(target foreign key)를
설정할 수도 있습니다. 이러한 작업을 수행하는 경우 필드에 대한 추가적인 매핑이 필요하게 됩니다.
내가 생성한 오브젝트에 프라이머리 키를
생성하고 할당하려면 어떻게 해야 합니까?
TopLink는 오브젝트를 데이터베이스에 INSERT하는 과정에서 유니크한 ID를 순차적으로 할당하는 기능을 지원합니다.
이 경우, TopLink는 오브젝트에 처음 액세스하는 경우에 ID를 할당하게 됩니다. IBM Informix, Microsoft
SQL Server, Sybase Adaptive Server의 네이티브 시퀀싱 기능을 이용하는 경우에는 INSERT
작업이 완료되기 전까지 ID를 확인할 수 없습니다.
또, 하나의 UnitOfWork 내에서 등록되는 모든 신규 오브젝트의 시퀀스 넘버는 assignSequenceNumber(Object)
메소드와 assignSequenceNumbers() 메소드를 통해 할당될 수 있습니다.
Foreign reference
매핑에서 외래 키에 전적으로 의존하지 않는 선택 기준(selection criteria)를 어떻게 정의할 수 있습니까?
Foreign reference mapping은 내부적으로 selection 쿼리를 사용하여 타겟으로부터 오브젝트를
읽어 옵니다. 여기서 사용되는 selection query는 다른 읽기 쿼리와 유사하며, 쿼리에 대한 고급 커스터마이즈
기능의 활용이 가능합니다. 복잡한 쿼리가 필요한 경우 Selection 쿼리 자체를 변경하여 커스텀 쿼리를 생성할
수도 있습니다. 외래 키에 전적으로 의존하지 않는 관계가 존재하는 경우, 매핑의 선택 기준을 위한 표현식을 아래와
같이 구현할 수 있습니다.
ExpressionBuilder builder
= new ExpressionBuilder(); mapping.setSelectionCriteria( builder.getParameter("EMPLOYEE.ADDR_ID").equal(builder.getField("ADDRESS.ID").and(builder.getField(
"ADDRESS.TYPE").equal("home"));
1:M 매핑으로 정의된 환경에서, 타겟 오브젝트에서
소스 오브젝트로의 1:1 매핑을 정의해야 하는 경우는 언제입니까? 다른 대안이 있습니까?
소스 오브젝트가 타겟 오브젝트에 대해 1:M 매핑으로 정의된 경우, 타겟 오브젝트에서 소스 오브젝트로의 1:1 매핑을
역으로 정의하고 타겟 테이블에 외래 키를 입력해야 합니다. 이러한 역매핑(back-mapping)이 정의되지 않은
경우, TopLink는 타겟 테이블에 외래 키 필드를 추가하는 작업을 수행할 수 없게 됩니다.
또는 AggregateCollectionMapping을 이용하여 단일 소스 오브젝트와 여러 개의 타겟 오브젝트 간의
aggregate (privately-owned) relationship을 정의할 수 있습니다. 이 경우 aggregation을
통해 외래 키 관계가 이미 설정되어 있기 때문에, 일반적인 1:M 매핑과 달리 1:1 역매핑을 설정할 필요가 없습니다.
외래 키 필드에 direct-to-field mapping을 정의하는 방법으로 1:1 역매핑을 피할 수도 있습니다.
이 경우, 오브젝트 모델이 소스 오브젝트의 정확한 값을 가져옴을 애플리케이션에서 보장해 주어야 합니다. 하지만 이러한
대안을 사용하는 경우 오브젝트 모델이 지나치게 복잡한 형태로 구현될 수도 있습니다. 따라서 1:1 역매핑을 사용하는
것이 권장됩니다.
또 다른 방법으로 소스로부터 타겟으로의 M:M 매핑을 정의하고 관계 테이블을 생성할 수도 있습니다. 이는 오브젝트
모델과 데이터 모델 간의 일관성을 보장할 수 있다는 점에서 최적의 대안으로 볼 수 있습니다. 이 경우 오브젝트 모델
또는 데이터 모델 중 어느 쪽에서도 타겟 오브젝트의 관계에 대한 정보를 저장하고 있지 않으며, 여러 개의 소스 오브젝트가
하나의 타겟 오브젝트를 참조하는 경우에도 지원이 가능합니다.
TopLink TypeConversionMapping이
써드 파티 클래스를 이용하도록 커스터마이즈하려면 어떻게 해야 합니까?
TopLink는 데이터베이스 타입과 Java 타입 간의 타입 변환을 위한 포괄적인 기능을 제공합니다. TopLink의
커스터마이즈 기능을 통해 도메인 클래스에 존재하는 써드 파티 타입을 추가적으로 활용하는 것 또한 가능합니다.
TopLink는 이를 위해 (oracle.toplink.helper package에 존재하는) ConversionManager를
사용합니다. 개발자는 이 클래스의 서브클래스를 생성하고, 커스텀 conversion manager를 생성할 수 있습니다.
단 시스템 기동 시, 이 클래스의 인스턴스를 singleton conversion manager로써 제시하여야 합니다.
2. 컬렉션 매핑(1:M, M:M,
DirectCollection)을 위한 값을 저장하는 경우 어떤 타입을 사용할 수 있습니까?
TopLink는 컬렉션에 대해 디폴트로 Vector 클래스를 사용합니다. TopLink는 매핑의 container
policy를 통해 다른 컬렉션 타입을 지원하기도 합니다. Collection 또는 Map 인터페이스를 구현하지 않는
다른 종류의 컨테이너를 사용하는 새로운 container policy를 정의할 수도 있습니다.
TopLink에서 BLOB 데이터를 매핑할 수 있습니까?
TopLink는 데이터베이스의 BLOB 데이터를 오브젝트 모델의 바이트 어레이(byte array)로 매핑합니다.
또 transformation, serialized mapping을 통해 BLOB을 오브젝트 모델의 complex
object로 매핑할 수도 있습니다. 일반적으로 JDBC 드라이버의 대규모 바이너리 데이터 지원 기능에 한계가 있기
때문에, TopLink는 여러 가지 대안을 함께 제공하고 있습니다. TopLink는 디폴트로 바이너리 데이터를 SQL
구문에 바인딩합니다. 또 TopLInk는 JDBC 바이너리 에스케이프 구문, 또는 네이티브 SQL을 이용한 데이터의
출력을 지원하기도 합니다.
바인딩은 DatabaseLogin의 dont/useByteArrayBinding() 속성을 통해 활성화/비활성화 처리됩니다.
바인딩이 활성화된 경우, TopLink 매개변수는 바이너리 값을 바인딩합니다. 일부 JDBC 드라이버에서 많은 수의
값을 바인딩하는데 문제가 있을 수 있지만, 스트림을 이용한 원활한 처리는 가능합니다. 이러한 이유로 TopLink는
스트림 바인딩을 함께 지원합니다. 스트림 바인딩은 DatabaseLogin의 useStreamBinding() 속성을
통해 활성화됩니다. 일부 드라이버는 BLOB 사이즈에 제한을 두고 있으며, 이 경우 바이너리 데이터를 여러 개의 필드로
분할하거나 direct collection 또는 1:M 매핑을 사용하여 데이터를 매핑해야 합니다.
대량의 문자열 데이터 역시 바인딩을 필요로 할 수 있습니다. DatabaseLogin의 useStringBinding(int)
속성을 이용하면 TopLink에서 문자열 데이터를 바인딩할 수 있습니다.
Serialized Mapping ? 또, TopLink는 관계형 테이블로 쉽게 매핑할 수 없는 오브젝트 구조를
SerializedObjectMapping을 통해 매핑하는 기능을 제공합니다. 이 매핑 타입은 루트 속성을 이용하여
오브젝트 구조를 순차화(serialize)하고, 데이터베이스의 BLOB 필드에 저장합니다. 오브젝트를 데이터베이스로
읽어오는 경우, 순차화 해제(de-serialize) 과정을 통해 기존 구조가 복원됩니다. 이러한 매핑은 개발자의
코딩을 요구하지 않으며, 구조 내의 오브젝트가 순차화되고 독립적(self-contained)임을 보장합니다.
TypeConversionMapping - Oracle JDBC 씬 드라이버(thin driver)는 LOB(BLOB,
CLOB) 정보의 읽기 및 쓰기를 위한 개선된 메소드를 지원합니다. TopLink에서도 이 드라이버를 이용하여
LOB 정보의 읽기/쓰기 작업을 수행할 수 있습니다. 매핑하고자 하는 데이터베이스 타입이 LOB(BLOB, CLOB)
타입임을 TopLink에 알리려면, TypeConversionMapping을 통해 속성의 매핑을 수행해야 합니다.
이와 같이 하면, TopLink는 적절한 메소드를 호출하게 됩니다.
SQL Exception에서
"invalid column name" 메시지가 뜨는 이유는 무엇입니까?
이 메시지는 SQL이 테이블에 존재하지 않는 컬럼에 쓰기 작업을 시도하는 경우에 발생합니다. 다음과 같은 이유를
생각해 볼 수 있습니다: foreign reference mapping에 정의된 필드 이름이 적절하게 명시되지 않은
경우. 컬럼 명의 스펠링이 잘못되었거나 소문자/대문자 표기를 잘못한 경우. 메소드에서 매핑을 위한 필드 이름이 정의된
부분을 확인해 보시기 바랍니다.
5. 시퀀싱(sequencing)을 설정한
후, 새로운 오브젝트를 INSERT 하려면 에러가 발생합니다. 무엇이 잘못되었습니까?
descriptor와 프로젝트의 시퀀싱 정보를 설정하였다 하더라도, 시퀀스 테이블(sequence table)이
초기화되지 않은 경우 이러한 문제가 발생할 수 있습니다. 시퀀스 테이블은 사용되는 각각의 시퀀스 이름에 대해 하나의
로우를 포함하고 있어야 하며, count 컬럼에 초기값이 저장되어 있어야 합니다. 예를 들어, Employee, Address의
descriptor가 시퀀싱을 시용하는 경우, 시퀀스 테이블은 아래와 같이 초기화되어야 합니다.
SEQ_NAME
SEQ_COUNT
EMPLOYEE
0
ADDRESS
0
6. TopLink의 상속 매핑(inheritance
mapping)은 Java 클래스의 상속과 어떻게 다릅니까?
TopLink가 Java 상속 계층을 매핑하는 경우, 계층 내의 각 클래스는 TopLink descriptor를
정의하고 있어야 합니다. 각 서브클래스의 descriptor는 부모 클래스가 자신의 수퍼클래스임을 정의하게 됩니다.
이러한 상속 계층을 데이터베이스에 반영하는 방법에는 여러 가지가 있습니다. TopLink는 모든 서브클래스가 공유하는
루트 클래스(root class)를 위한 공통 테이블을 정의할 것을 요구하고 있습니다. 서브클래스는 추가적인 데이터를
저장하기 위해 테이블을 추가로 정의하거나, 부모 클래스의 테이블을 자유롭게 공유할 수 있습니다. TopLink는 루트
테이블의 indicator 필드를 이용하여 로우에서 인스턴스화(instantiate)하는 클래스를 결정합니다. 하지만
필요한 경우 이러한 메커니즘을 커스터마이즈 할 수도 있습니다.
루트 도메인 클래스를 보유한 시스템을 반드시 이러한 형태의 상속 매핑을 통해 매핑해야 하는 것은 아닙니다. 이러한
작업은 데이터베이스 스키마에서 별도로 요구되는 경우, 또는 오브젝트 모델이 유사한 타입을 함께 저장하도록 허용하는
경우에만 요구됩니다. 루트 클래스를 위한 테이블을 정의할 필요가 없다고 판단되는 경우라면, 루트 클래스를 아예 매핑하지
않거나 또는 인터페이스로 매핑할 수도 있습니다. TopLink는 interface descriptor에 대한 쿼리를
지원하며, 루트 테이블의 데이터베이스 테이블 매핑을 필수적으로 요구하지 않습니다.
매핑된 상속 계층에서, 모든 서브클래스는 루트의 프라이머리 키를 공유해야만 합니다. 테이블이 여럿 존재하는 경우,
추가된 테이블의 프라이머리 키는 루트 테이블에 위치한 프라이머리 키와 다른 이름으로 명명되어야 합니다. 이 경우,
네임 매핑(name mapping)은 descriptor에 의해 수행되며, 구성이 복잡한 경우 테이블 JOIN을 통해
수행될 수도 있습니다. 루트 테이블의 프라이머리 키는 TopLink에 의해, 또는 캐싱을 위해 항상 내부적으로 사용되게
됩니다.
7.
많은 수의 상속을 포함하는 도메인 모델이 있습니다. 이 경우 TopLInk에서 상속을 모두 모델링해야만 합니까?
아닙니다. TopLink 내에서의 상속은 수퍼클래스로의 쿼리 또는 쓰기 작업이 필요한 경우에만 관계형 모델링이 필요합니다.
클래스 A가 서브클래스 B를 포함하는 경우를 생각해 봅시다. A에는 id와 description이라는 두 가지 속성이
존재합니다. 한편, B에 대응되는 데이터베이스 테이블에는 ID 필드와 DESCRIPTION 필드가 존재하지만, A에
대응되는 테이블은 존재하지 않습니다. 이 경우 TopLink에서 B에 대한 매핑만을 수행하고 수퍼클래스 A는 무시할
수 있습니다. A에 포함된 필드는 매핑 B를 통해 매핑이 가능합니다.
이와 같은 작업을 통해 오브젝트 모델을 매핑하는 한편, 퍼시스턴스가 요구되지 않는 특정 클래스(abstract class,
"PersistentObject" superclass 등)를 무시할 수 있습니다.
8. 특정 매핑에
대해 Transparent Indirection을 설정하였습니다. 이 설정을 적용하기 위해 추가적으로 작업해 주어야 하는
것이 있습니까?
일반적으로는 추가 작업이 불필요합니다. 하지만, 속성이 올바른 타입으로 정의되었는지 확인해 줄 필요가 있습니다.
collection indirection의 경우, 속성 타입이 java.util.Collection으로 설정되었는지
확인해야 합니다. one-to-one indirection의 경우에는 속성 타입이 인터페이스로 정의되었는지 확인해야
합니다 (TopLink는 타겟 오브젝트를 타겟 클래스와 동일한 인터페이스를 구현한 스페셜 래퍼 오브젝트로 대체합니다).
변수가 올바른 타입으로 정의되지 않은 경우, TopLink는 변수에 값을 할당할 수 없습니다.
Serialization으로 인해 Transparent Indirection에 문제가 발생할 가능성도 있습니다. Remote
Session이 사용되지 않는 이상, Transparent Indirection은 클라이언트에서 인스턴스화(instantiate)
될 수 없습니다. 이는 일반적인 indirection의 경우에도 마찬가지입니다. 하지만 Transparent Indirection의
경우 indrection이 인스턴스화되는 위치가 다릅니다. 고전적인 방식의 ValueHolder를 사용하므로, indirection은
getAttribute() 메소드가 호출되는 시점에 트리거됩니다. Transparent Indirection을 사용하여
참조되는 오브젝트가 클라이언트에 의해 접근될 수 있으려면, 먼저 서버에서 클라이언트에 메시지를 전송해 주어야 합니다
(예를 들어 transparent collection을 위해서는 getSize()를, transparent one-to-one을
위해서는 hashCode() 등이 전송되어야 합니다).
9. TopLink는 사용자 정의 오브젝트/데이터
변환의 플러그인을 위한 방법을 제공합니까?
네. 커스텀 변환의 정의를 위해서는 Transformation Mapping이 사용됩니다.
자세한 정보는 <OracleAS TopLink Application Developer's Guide>의
Transformation
Mappings를 참고하시기 바랍니다.
lazy loading (indirection)을
사용하려면 매핑을 어떻게 설정해 주어야 합니까?
1:1 또는 1:M 관계를 위한 lazy loading은 MappingWorkbench또는JDeveloper Mapping
Editor를 통해, 또는 Java에서 직접 설정이 가능합니다.
11. owner 오브젝트가
삭제된 경우 관련 오브젝트를 모두 삭제하도록 (cascade delete 기능을 사용하도록) TopLink를 설정하려면
어떻게 해야 합니까?
TopLink에서는 owner 오브젝트와 라이프사이클이 연계된 오브젝트를 “privately owned” 오브젝트라
부릅니다. Privately owned 오브젝트는 부모 오브젝트가 삭제되는 경우 함께 삭제됩니다. MappingWorkbench
또는 JDeveloper Mapping Editor를 사용하여, 또는 Java에서 직접 descriptor를 수정하여
“privately owned” 오브젝트를 설정할 수 있습니다.
EJBQL, SQL 이외에도, TopLink는 오브젝트 모델의 형태로 구현될 수 있는 거의 모든 종류의 쿼리를 지원하고
있습니다. 이러한 쿼리들은 런타임에 SQL로 다이내믹하게 변환됩니다.
TopLink Mapping Workbench를 이용하여 descriptor를 정의하는 경우, Queries 탭을
이용하여 EJB QL 또는 SQL 쿼리를 명시하고 데이터베이스 액세스를 위해 사용할 파인더(finder)를 정의할
수 있습니다. Queries 탭에는 2개의 탭(Named Queries와 Custom SQL)이 추가로 포함되어 있습니다.
2.0 CMP 프로젝트의 경우, ejb-jar.xml 파일에 쿼리 리스트가 저장됩니다. 이 파일에서 쿼리를 정의한
후 TopLink Mapping Workbench에서 불러오거나, Queries 탭에서 쿼리를 정의한 후 정의 결과를
파일에 쓸 수 있습니다.
TopLink 쿼리는 EJBQL을 지원합니까?
ReadAllQuery와 ReadObjectQuery의 setEJBQLString(String EJBQLString)
메소드를 이용하면 EJBQL을 포함하는 String에 대한 쿼리의 선택 기준(selection criteria)을
설정할 수 있습니다.
TopLink Mapping Workbench는 EJB QL 쿼리 또한 지원합니다.
TopLink가 지원하는 Expression
관련 기능으로 무엇이 있습니까?
TopLink는 이용하면 거의 모든 종류의 쿼리를 오브젝트 모델의 형태로 변환할 수 있습니다.
이러한 쿼리는 런타임에 SQL 구문으로 다이내믹하게 변환됩니다. TopLink의 expression framework가
지원하는 구성요소가 아래와 같습니다:
=, !=, <, <=, =, >, >=, in, like, between 등의 연산자
AND, OR, NOT 등의 논리 연산자
1:1, 1:M, M:M 관계의 트레버싱(traversing), 조인(join) 등 (대부분의 데이터베이스에
대해outer join 지원)
일부 데이터베이스 제품, 또는 데이터베이스 설정의 경우, 테이블 소유자 또는 테이블스페이스 이름에 대해 테이블 이름을
대조(qualify)해야 할 필요가 있을 수 있습니다. TopLink는 이러한 작업을 세션 단위로, 또는 개별 descriptor
단위로 수행하는 기능을 지원합니다.
세션에 로그인하기 전에 아래 메소드를 DatabaseLogin 오브젝트에 전송하면, 등록된 모든 descriptor의
테이블 명이 creator 또는 qualifier name과 대조됩니다.
login.setTableQualifier("PERSONNEL");
각각의 qualifier는 TopLink Mapping Workbench를 통해 테이블 단위로 입력됩니다.
서브클래스 인스턴스를 제외한 부모
클래스 인스턴스만을 쿼리하도록 클래스를 설정하려면 어떻게 해야 합니까?
디폴트 설정에서 부모 클래스를 조회하면, 부모 클래스와 서브클래스의 모든 인스턴스가 반환됩니다. 부모 클래스의 인스턴스만을
조회하고자 하는 경우, “should read subclasses” 상속 속성을 부모 클래스의 descriptor에서
비활성화해야 합니다. 특정 쿼리에 대해 서브클래스 인스턴스의 조회가 필요하지 않은 경우 서브클래스를 필터링하도록 쿼리를
설정할 수 있습니다. 서브클래스 필터링을 위한 expression의 예가 아래와 같습니다:
Expression builder = new ExpressionBuilder();
Expression expression = builder.getField("typeIndicatorField").equal("parent");
QueryByExample
오브젝트와 selection 오브젝트의 차이는 무엇입니까?
QueryByExample 오브젝트는 쿼리의 selection 오브젝트를 대체할 수 없습니다. QueryByExample
오브젝트는 다양한 속성 값을 갖는 오브젝트를 생성하고, 쿼리에 대한 컨트롤을 강화하기 위한 목적에서 사용됩니다. selection
오브젝트는 프라미어리 키만을 이용해서 쿼리를 수행하기 위한 간결한 메커니즘을 제공합니다. selection 오브젝트의
다른 모든 속성은 무시됩니다.
하나의
expression에 대해 두 개 이상의 ExpressionBuilder subexpression을 사용할 수 있습니까?
사용할 수 없습니다. 경우에 따라서 사용 가능한 것처럼 보일 수도 있지만, join과 같은 복잡한 expression이
적용되는 경우 실패하게 됩니다. 따라서 하나의 expression에서는 동일한 ExpressionBuilder만을
사용하는 것이 권고됩니다.
단, expression이 subselect를 포함하는 경우, 서브 쿼리에 다른 ExpressionBuilder가
사용될 수는 있습니다.
사용 중인 expression에
여러 개의 anyOf( ) 함수를 적용하는 경우, 반복적인 JOIN 작업으로 인해 지나치게 많은 결과가 반환됩니다. JOIN의
회수를 1회로 줄이려면 어떻게 해야 합니까?
Expression에서 anyOf()를 사용할 때마다, 데이터베이스에 새로운 JOIN이 발생하게 됩니다. 아래와
같은 TopLink expression을 고려해 봅시다:
emp.anyOf("managedEmployees").get("lastName").equal("Smith").and(emp.anyOf("managedEmployees").get("firstName").equal("John"));
위 expression을 실행하면 John Smith 뿐 아니라 John 또는 Smith의 관리자로 있는 모든 Employee가
반환됩니다. 이는 각각의 anyOf()에 대해 별도의 JOIN 작업이 수행되기 때문입니다.
하나의 JOIN으로 구문을 묶으려면, 각 쿼리에 대해 동일한 anyOf 노드가 사용되어야만 합니다:
일부 JDBC 드라이버는 JDBC에서 사용하는 날짜 문법을 지원하지 않습니다. 이러한 경우를 위해, TopLink는
네이티브 데이터베이스 문법으로 날짜를 표시하는 기능을 지원합니다. 네이티브 SQL 출력을 사용하려는 경우 DatabaseLogin의
useNativeSQL() 속성을 설정해야 합니다.
데이터베이스에서 날짜 값을 읽어 오는
과정에서 conversion exception이 발생하는 이유는 무엇입니까?
TopLink optimizes how data is converted from the JDBC driver. This
includes date type where TopLink handles the conversion from strings
internally. Some JDBC drivers, when returning the string representation
of the date, return the wrong string syntax. In this case use the
dontOptimizeDataConversion() property in DatabaseLogin to disable
this optimization.
How do I query historical
data?
TopLink는 JDBC 드라이버의 데이터 변환 과정을 최적화합니다. date 타입을 처리하는 경우에도, TopLink는
내부적으로 문자열을 처리하게 됩니다. 일부 JDBC는 날짜 데이터를 문자열로 반환하는 과정에서 잘못된 문법을 사용하기도
합니다. 이 경우 DatabaseLogin의 dontOptimizeDataConversion() 속성을 사용하여 TopLink의
최적화 기능을 비활성화해야 합니다.
1. 데이터베이스에서 처음 오브젝트를 읽어올 때보다
두 번째 읽어올 때 더 빠른 이유가 무엇입니까?
특정 클래스에 대해 캐싱이 활성화 된 경우, 해당 클래스의 인스턴스를 두 번째 읽어오는 속도는 처음 읽어오는 속도보다
빠릅니다. 이것은 TopLink가 캐시에 저장된 오브젝트를 이용하여, 데이터베이스로부터 오브젝트를 구성하는 시간을
절감하기 때문입니다. 캐싱은 클래스 단위로 설정되며, 다양한 캐시 타입의 설정이 가능합니다.
TopLink는 descriptor에 정의된 오브젝트의 프라이머리 키 필드 값을 이용하여 오브젝트를 구분합니다.
오브젝트 캐시는 DatabaseSession 또는 ServerSession에서 관리되며, 캐시 오브젝트는 클래스 및
프라이머리 키 값을 기준으로 생성됩니다.
TopLink는 오브젝트의 아이덴티티
정보를 어떻게 구분합니까?
각각의 클래스 타입은 DatabaseSession 또는 ServerSession 내부에 아이덴티티 맵(identity
map)을 가지고 있습니다. 오브젝트는 오브젝트에 정의된 프라이머리 키 필드값을 기준으로 아이덴티티 맵에 저장됩니다.
TopLink는 읽기 작업 과정에서 캐시를 점검하여 (오브젝트에 매핑되는) 특정 관계형 데이터에 대해서 단 하나의
클래스 인스턴스만이 존재함을 확인함으로써, 동일한 오브젝트의 반복적인 읽기 작업을 통해 동일한 참조가 반환됨을 확인하고
오브젝트 아이덴티티(object identity)를 보장합니다. 이러한 메커니즘은, 애플리케이션에 발생한 오브젝트
변경사항이 해당 오브젝트를 사용하는 다른 사용자의 환경과 동기화됨을 가능하게 합니다. 또 오브젝트 아이덴티티는 순환
레퍼런스(circular reference)를 사용하는 복잡한 구조가 무한 루프에 빠지는 위험을 방지합니다.
이미 데이터베이스 또는 캐시에 존재하는 (동일한 클래스, 프라이머리 키의) 오브젝트를 생성하려 시도하는 경우 오브젝트
아이덴티티 위반 에러가 발생합니다.
TopLink가 제공하는 캐싱 옵션에는 어떤 것이 있습니까?
TopLink는 6가지 캐시 타입을 지원합니다. 캐시 타입은 클래스 단위로 설정됩니다.
None (NoIdentityMap )
Full (FullIdentityMap )
Cache (CacheIdentityMap, 고정 크기, 가장 최근에 사용된 오브젝트를 drop)