Hibernate3.x Migration Guide (work in progress - 2005년 12월 13일 현재.)#

Hibernate 3.0은 Hibernate 2.1과 소스가 호환되지 않는다. 그리고 2.1을 위해 삽입식 교체처럼 의도하지 않았다. 어쨌든 3.0으로의 교체는 코드와 메터데이터 모두에게 일관된 이주를 허락하도록 디자인되었다. 대부분의 프로젝트는 이주시 많은 어려움을 겪지는 않을것이다.

이 문서는 존재하는 애플리케이션에게 영향을 끼칠수 있는 Hibernate 2.1과 3.0사이의 변경를 서술하고 존재하는 애플리케이션에 유용할수 있는 Hibernate 3.0의 새로운 기능을 언급한다.

변경는 API변경, 자바코드에 영향, 메터데이터 변경, XML O/R맵핑 메터데이터에 영향 그리고 쿼리언어 변경, HQL쿼리의 영향등으로 분류된다.

이것은 같은 애플리케이션에서 Hibernate 2.1과 Hibernate 3.0이 병행해서 수행될수 있도록 한다.

Hibernate 3.0

  • API Changes[1]
    • Package naming[2]
    • org.hibernate.classic package[3]
      • Session interface[4]
      • createSQLQuery()[5]
      • Lifecycle and Validatable interfaces[6]
    • Dependencies[7]
    • Exception model[8]
    • Interceptor interface[9]
    • UserType and CompositeUserType interfaces[10]
    • FetchMode[11]
    • PersistentEnum[12]
    • Blob and Clob support[13]
    • Changes to extension APIs[14]
  • Metadata Changes[15]
    • Association fetching strategies[16]
    • Identifier mappings[17]
    • Collection mappings[18]
    • DTD[19]
  • Query Language Changes[20]
    • indices() and elements() functions[21]
  • Configuration changes[22]
    • BEA Weblogic issues[23]

Hibernate 3.1

  • API changes[24]
    • Updates to NamingStrategy interface[25]
    • Event listeners[26]
  • Configuration changes[27]
    • JDBC connection release mode[28]
    • Event listeners[29]

Hibernate 3.0#

API 변경[#1]#

패키지 명명[#2]

Hibernate3은 net.sf.hibernate 대신에 org.hibernate가 가장 상위가 되는 패키지 구조로 변경되었다. 이름변경은 Hibernate2와 Hibernate3이 같은 애플리케이션내에서 병행해서 수행되도록 허락한다. Hibernate3 이주의 첫번째 과정은 전체적인 텍스트 검색/교체이다. 예를 들면 s/net.sf.hibernate/org.hibernate.

net.sf.hibernate.expression 패키지는 org.hibernate.criterion으로 이름이 변경되었다. Criteria쿼리를 사용하는 애플리케이션은 이 변경을 달성하기 위해서 텍스트/검색 교체를 요구한다.

만약 당신이 Hibernate패키지를 참조하는 다른 외부적인 소프트웨어를 사용한다면(즉 예를 들면 EHCache는 net.sf.ehcache.hibernate.Provider내에서 자신만의 CacheProvider를 가진다. ) 다른 외부적인 소프트웨어가 모두 이 참조를 수정할때까지 당신은 패치해야 하고 이 사항에 유념해서 작업해야 한다. EHCache를 위해서 당신은 Hibernate내에 고유의 provider(org.hibernate.cache.EhCacheProvider)를 사용할수도 있다.

org.hibernate.classic 패키지[#3]

Hibernate3에서 deprecated된 몇몇 인터페이스는 org.hibernate.classic 패키지로 이동되었다.

Session 인터페이스[#4]

장황한 메소드가 org.hibernate.Session인터페이스로부터 deprecated되거나 삭제되었다. 어쨌든 이주를 쉽게하기 위해서는 다음의 메소드들은 org.hibernate.classic.Session하위 인터페이스를 통해서 여전히 사용가능하다. deprecated된 메소드는

  • 쿼리 수행 메소드: find(), iterate(), filter(), delete()
  • saveOrUpdateCopy()

Hibernate3 애플리케이션은 모든 쿼리수행을 위해서 createQuery(), 대량 삭제를 위한 DELETE쿼리 그리고 saveOrUpdateCopy() 대신에 merge()를 사용해야만 한다. 존재하는 애플리케이션은 deprecated메소드를 계속적으로 사용할수 있을것이다.

DELETE쿼리는 deprecated된 delete(hqlSelectQuery)로부터 조금 차이가 있고 일관적으로 교체하지 않는 EJB3을 고려한다는것을 명심하라. session.delete(object)는 여전히 존재하고 의존적인 엔터티에 삭제작업을 단계적으로 수행하는것을 포함해서 하나의 영속적인 인스턴스를 제거하는데 사용할수 있다. 이것은 depreacated된 delete(hqlSelectQuery)메소드처럼 같은 의미/결과를 얻기 위해 사용될수 있다.

createSQLQuery()[#5]

배열을 가져오는 createSQLQuery()의 지나치게 많은 형식들은 deprecated되고 org.hibernate.classic.Session으로 이동되었다. 상응하는(또는 더 많은) 기능을 제공하는 새로운 SQLQuery인터페이스가 있다. 존재하는 애플리케이션은 아마 deprecated된 메소드를 계속적으로 사용할수 있을것이다.

Lifecycle 과 Validatable 인터페이스[#6]

Lifecycle 와 Validatable인터페이스는 Hibernate3에서 deprecated되고 org.hibernate.classic패키지로 이동되었다. Hibernate팀은 영속성정의 API들에 의존적인 도메인모델 클래스를 가지기 위한 좋은 연습(practice)이라는 것을 숙고하지 않는다. Hibernate3애플리케이션은 Interceptor또는 새로운 Hibernate3 이벤트 프레임워크를 사용해야만 한다. 존재하는 애플리케이션은 아마 계속적으로 Lifecycle 과 Validatable를 사용할것이다.

의존성[#7]

lib/README.txt 내의 요구되는 외부 라이브러리를 보라. 몇몇은 수정되었고 몇몇 새로운것이 필요하다.

예외(Exception) 모델[#8]

HibernateException 과 다른 모든 Hibernate 예외는 지금 체크되지 않는(unchecked) runtime exceptions이다.

Interceptor 인터페이스[#9]

두개의 새로운 메소드는 Interceptor인터페이스에 추가되었다. 존재하는 Interceptor들은 두개의 새로운 메소드의 빈 구현을 제공하기 위해서 업그레이드 할 필요가 있을것이다. instantiate()의 시그너처(signature)는 클래스 객체대신에 문자열값의 엔터티 이름을 가져오도록 변경되었다. isUnsaved()메소드는 isTransient()으로 이름이 변경되었다.

UserType 과 CompositeUserType 인터페이스들[#10]

UserType 과 CompositeUserType 둘다 Hibernate3의 새로운 기능을 제공하기 위해 추가된 다양한 메소드를 가진다. 그것들은 org.hibernate.usertype패키지로 이동되었다. 존재하는 사용자 타입 클래스는 이 새로운 메소드를 구현하기 위해 업그레이드 할 필요가 있을것이다.

주의: Hibernate3은 사용자 타입 구현의 좀더 향상된 재사용성을 가능하게 하는 ParameterizedType를 제공한다.

FetchMode[#11]

FetchMode.LAZY 와 FetchMode.EAGER는 deprecated되었다. 좀더 정확한 이름의 FetchMode.SELECT 과 FetchMode.JOIN이 같은 영향을 끼치도록 되었다.

PersistentEnum[#12]

deprecated된 PersistentEnum는 Hibernate3에서 삭제되었다. 존재하는 애플리케이션은 영속적인 열거된 타입을 다루기 위해서 UserType을 사용해야만 한다.

Blob 와 Clob 지원[#13]

Hibernate는 현재 Blob와 Clob인스턴스를 분리되고, 직렬화되거나 역직렬화되고, merge()에 전달될 수 있는 Blob또는 Clob타입의 속성값을 가진 클래스를 허락하도록 포장한다. 어쨌든 이것은 Blob또는 Clob가 업체정의타입(예를 들면 oracle.sql.Clob)로 변환될수 없다는 것을 의미한다. 당신은 getWrappedClob() 또는 getWrappedBlob()메소드를 사용해야만 한다.

clob = (oracle.sql.CLOB) ( (org.hibernate.lob.SerializableClobfoo.getText() ).getWrappedClob();
우리는 Oracle이 JDBC드라이버에서 이부분을 수정할때 이런종류의 것들이 더이상 필요하지 않을것이라고 기대한다.

확장 API에 대한 변경[#14]

org.hibernate.criterion, org.hibernate.mapping, org.hibernate.persister 그리고 org.hibernate.collection 패키지는 리팩토링 되었다. 대부분의 Hibernate2.1애플리케이션은 이런 패키지에 의존하지 않고 영향을 끼치지도 않을것이다. 만약 당신의 애플리케이션이 이러한 패키지를 확장한다면 당신은 영향을 끼치는 코드를 조심스럽게 이주시킬 필요가 있을것이다.

메터데이터 변경[#15]#

Association fetching 전략[#16]

lazy="true" 를 사용해서 모든 클래스와 컬렉션(collections)을 맵핑하는 것이 가장 좋은 예가 되면서 부터 이것은 지금 디폴트가 되었다. 존재하는 애플리케이션은 모든 non-lazy상태의 클래스와 컬렉션맵핑일때만 lazy="false"를 명시적으로 선언할 필요가 있을것이다.

outer-join 속성은 deprecated되었다. outer-join="true" 과 outer-join="false" 대신에 fetch="join" 과 fetch="select" 를 사용하라. 존재하는 애플리케이션은 outer-join속성을 계속적으로 사용하거나 fetch속성값을 사용하는 것으로 이주하기 위해 텍스트 검색/교체를 사용할수 있다.

알아둬라. 이것은 당신이 이전에 "lazy" 속성을 가지지 않는 모든 컬렉션맵핑과 클래스에 lazy="false"를 두는것을 의미한다.

이주를 위한 빠르고 지저분한 대안은 당신의 모든 hibernate-mapping 요소에 default-lazy="false"를 두는것이다.

구분자 맵핑[#17]

unsaved-value속성은 지금 옵션적인(필수가 아닌)것이다. 대부분의 경우 Hibernate는 민감한 곳에 디폴트로 unsaved-value="0"을 사용할 것이다.

주의 : Hibernate3에서 이것은 natural 키(할당된 구분자또는 복합 구분자)와 분리된 객체들을 사용할때 Interceptor.isUnsaved()를 구현하는 것은 더 이상 필요하지 않다. 어떤 "힌트"의 부족으로 인해 Hibernate는 만약 객체가 새로 생성되거나 분리된다면 이것을 판단하기 위해 데이터베이스를 쿼리할것이다. 어쨌든 Interceptor.isUnsaved()의 사용은 데이터베이스 쿼리를 피할수 있기 때문에 좀더 높은 성능의 결과를 야기한다.

Collection 맵핑들[#18]

<index> 요소는 부분적으로 deprecated되었다. <list-index> 와 <map-key> 는 지금 선호된다. <map-key-many-to-many>는 <key-many-to-many>에 선호되고 <composite-map-key>는 <composite-index>에 선호된다.

DTD[#19]

당신의 hbm XML파일내의 DTD참조는 수정되었다. DOCTYPE에서 http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd 를 http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd 으로 변경하라.

Query 언어 변경[#20]#

Hibernate3은 ANTLR기반의 HQL/SQL쿼리 분석자로 아주 새롭게 다가왔다. 어쨌든 Hibernate2.1 쿼리 파서는 여전히 사용가능하다. 쿼리 파서는 Hibernate프라퍼티인 hibernate.query.factory_class을 셋팅함으로써 선택할수 있다. 가능한 값은 새로운 쿼리 파서를 위해서 org.hibernate.hql.ast.ASTQueryTranslatorFactory이고, 예전의 파서를 위해서는 org.hibernate.hql.classic.ClassicQueryTranslatorFactory이다. 우리는 Hibernate2.1에 의해 허락된 모든 쿼리를 지원하도록 새로운 쿼리 파서를 매우 열심히 작업중이다. 우리는 존재하는 이미 많은 애플리케이션이 이주 절차를 거치는 동안 Hibernate2.1파서를 사용할 필요가 있을 것이라고 생각한다.

Hibernate 1.x문법인 "from f in class bar.Foo" 는 더이상 지원되지 않는다. "from bar.Foo as f" 또는 "from bar.Foo f" 을 사용하라.

주의 : theta 스타일 outer join으로 dialects(예를 들면. Oracle 8i를 위한 OracleDialect, TimesTen dialect, Sybase11Dialect).에 영향을 끼치는 몇몇 알려진 버그가 있다. ANSI스타일의 조인을 지원하는 dialect(예를 들면. Oracle9Dialect)을 사용하거나 문제점을 겪었을때 예전 쿼리 파서를 사용하도록 하라.

indices() 과 elements() 함수들[#21]

indices() 와 elements() 구조는 HQL select요소에서 더이상 나타나지 않을것이다(이것의 의미가 사용자에게 매우 혼돈스러웠다.). 그들은 여전히 where()요소내에 사용될것이다. select요소들 대신에 명시적인 조인을 사용하라.

설정상의 변경[#22]#

BEA Weblogic 에 관련된 이슈들[#23]

Hibernate3은 새로운 쿼리 파서를 위해 ANTLR을 사용한다. 운없게도 BEA Weblogic은 어떠한 애플리케이션 라이브러리이전에 로드될 시스템 클래스패스내에 ANTLR을 포함한다. weblogic이 클래스로더 격리를 지원하지 않기 때문에 애플리케이션 컨텍스트내에서 Hibernate를 볼수 없을것이다. BEA는 이 패키지 이름을 수정(패키지 접두사를 사용함으로써)함으로써 이 사항을 해결할려고 하는것처럼 보인다. 하지만 배포되는 ANTLR은 이러한 접두사를 가지지 않는다. 이 사항을 위한 다른 소스는 ANTLR스스로 Class.forName()의 사용이다.

이 문제가 해결될때까지 우리가 할 수 있는 방법이 있다. 하나는 당신의 모든 Hibernate와 의존적인 라이브러리를 애플리케이션 서버의 부트 클래스패스에 두거나 위에서 서술된 예전 쿼리 파서를 사용하는것이다.

Hibernate팀은 ANTLR개발자에게 이 사항에 대한 수정사항을 보냈고 이는 다음번 릴리즈에 포함될것이다. 우리는 조만간 Hibernate에 새 버전에 이를 포함시킬것이다.

Hibernate 3.1#

Hibernate 3.1은 많은 새로운 기능을 가진 Hibernate 3.0을 위한 상대적으로 작은 단위(minor)의 업그레이드이다. 우리는 다른 면에서는 Hibernate 3.0을 위한 단순한(drop-in) 대체물이길 기대한다. 당신은 새로운 JAR파일을 사용하여 3.1로 업그레이드 할수 있다.

어쨌든. 몇가지의 변경된 점들은 Hibernate 3.1이 예전 방식에 의존하는 코드가 가진 문제점을 야기할수도 있다. 우리는 여기에 그것들을 언급하고자 한다.

<div class="note"> 아래의 트랜잭션 부분은 공식적인 문서에서는 삭제된 부분입니다. </div> 트랜잭션 -- 몇몇 API는 Hibernate 3.1에서 말끔하게 정리가 되었다. 특히 Session의 경우가 그렇다. Disconnect()와 reconnect() 메소드는 deprecated 되었다. Session은 데이터베이스 트랜잭션이 끝난 이후에 JDBC connection으로부터 연결이 끊길것이다(disconnect). 그리고 데이터베이스 트랜잭션이 시작되기 전까지는 새로운 connection을 얻지 않을것이다. 이것은 신뢰할만한 트랜잭션 경계를 가지지 않는 애플리케이션에서는 “connection을 얻을수 없습니다.” 와 같은 에러를 야기한다. 당신은 애플리케이션에서 자동커밋을 사용하지 않을수 있고 사용하지 않아야만 한다.

API 변경사항[#24]#

NamingStrategy인터페이스에 대한 업데이트[#25]

만약 당신이 사용자정의 NamingStrategy를 구현했다면, 당신은 그 인터페이스의 새로운 메소드에 대한 구현을 추가하거나 DefaultNamingStrategy 또는 ImprovedNamingStrategy를 확장해야할것이다.

Event listeners[#26]

당신은 이벤트마다 다양한 이벤트 리스너를 플러그인할수 있다. 그래서 EventListeners API는 이벤트당 하나의 리스너 객체대신에 리스너 배열을 받아들일수 있도록 변경되었다. 당신은 Hibernate의 디폴트 리스너를 확장하는 리스너를 만들수 있지만 디폴트 리스너로부터 상속하는 대신에 그러한 리스너를 연결하는 능력을 가지도록 검토하길 원할것이다.

설정상의 변경사항[#27]#

JDBC 연결 해제 모드[#28]

이전 버전은 Hibernate 2.x와의 이전버전과의 호환성을 위해 ON_CLOSE로 디폴트화되었다. 3.1에서 어쨌든, 디폴트는 "auto"이다. 대개 이것은 디폴트값을 단순히 오버라이드하지 않기 위해서는 최적의 값이다. 만약 당신의 애플리케이션이 이전 버전의 특성(사용가능한 트랜잭션 경계에서 같은 connection을 가지는것과 같은)에 의존한다면, 당신을 이것을 조정해야 할것이다. 하지만 당신은 애플리케이션 로직을 가진 문제처럼 이것을 보고 고쳐야만 한다. 또는 당신이 "트랜잭션 없이 데이터를 읽거나 트랜잭션 밖에서 데이터를 읽을수" 있다고 믿는다면, 당신은 Hibernate3.1에서 이 문제에 직면할것이다. 물론 트랜잭션 밖에서 데이터접근을 하지 않을수 있다. 그리고 Hibernate 3.1은 자동커밋 영향에 의존하는 나쁜 코드를 작성하는 것이좀더 어렵도록 만든다. 좀더 상세한 정보를 위해서는 3.1문서내 11.5장을 보라.

이벤트 리스너[#29]

모든 리스너는 지금 이벤트당 다양한 이벤트 리스너를 지원한다. hibernate.cfg.xml은 <listener>대신에 그것들을 설정하기 위해 좀더 적절한 <event>요소를 사용해야만 한다.

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-12) was last changed on 06-Apr-2006 09:45 by 이동국