Migrate To Hibernate 3.2

API 변경사항

BytecodeProvider extension

  • 하이버네이트의 바이트코드 처리에 필요한 라이브러리를 추가할 수 있는 기능을 추가했다. 이전에는 CGLIB만 사용했는데, 이제는 CGLIB과 Javassist 중에 하나로 선택할 수 있다.

행동 변경사항

Non-transactional access

  • FlushMode.AUTO는 Session내의 변경을 모두 SQL을 실행해서 반영한다. 트랜잭션 범위가 아닐 경우에 auto flush는 생략된다.
  • Second has to do with identifiers generated via an
    “in-database” strategy (the so-called post-insert id generators). Saves
    to such entities in previous versions caused an immediate SQL INSERT to
    be issued in order to determine the generated identifier value.
    Starting with 3.2, these INSERTS will be delayed when done outside of a
    transaction.

쿼리 언어 변경사항

Implicit joins are more deterministic

<class name='Currency' lazy='false'>
....
</class>

<class name='Asset'>
<id name='id' ... </id>
<many-to-one name='currency' class='Currency' fetch='select'/>
</class>
  • select a.id, a.currency from Asset a 이런 쿼리는 inner join을 생성한다.
  • select a.id, c from Asset a left join a.currency as c 이렇게 해야 currency가 Null Asset도 전부 가져온다.

Path expressions joining across a collection throw exception

  • select f.bars.baz from Foo f 이런 네비게이션은 이제 에러난다.
  • select b.baz from Foo f join f.bars b 이렇게 써야 한다.

Changed aggregation (count, sum, avg) function return types

  • 스펙에 맡게 리턴타입이 바꼈다.
  • COUNT는 Long을 반환한다.
  • MAX와 MIN은 적용된 필드 타입을 반환한다.
  • AVG는 Double을 반환한다.
  • SUM은 정수타입이 경우에는 Long을 반환한다. 실수일 경우에는 Double, BidInteger일 경우에는 BidInteger, BigDecimal일 경우에는 BidDecimal.
  • 이전 타입을 쓰려면 다음의 코드를 추가한다.
Configuration classicCfg = new Configuration(); 
classicCfg.addSqlFunction( "count", new ClassicCountFunction());
classicCfg.addSqlFunction( "avg", new ClassicAvgFunction());
classicCfg.addSqlFunction( "sum", new ClassicSumFunction());
SessionFactory classicSf = classicCfg.buildSessionFactory();

Improved parameter type guessing

  • 이전에는 파라미터의 타입을 넘어온 값으로 판단했는데, 이제는 쿼리르 보고 판단한다.

Expanded component support

  • First is the ability to bind complete components as parameter values.
Name name = new Name();
name.setFirst( "John" );
name.setLast( "Doe" );
List johnDoes = session.createQuery( "from Person where name = :name" )
.setParameter( "name", name )
.list();
  • ANSI SQL 처럼 “row balue contructor”를 사용할 수 있다.
List johnDoes = session.createQuery( "from Person where name = ('John', 'Doe')" ).list();

Improved boolean literal and parameter handling

  • List pregs = session.createQuery( “from Animal where pregnant = true” ).list(); 이런 쿼리에서의 true 역시 쿼리를 분석하여 SQL을 만들어 낸다.

Native SQL 쿼리 변경사항

Sequence of return values from native sql queries (createSQLQuery() and getNamedQuery())

  • 이전에는 scalar 먼저, entity는 그 다음 순으로 반환했다.
  • 3.2에서 그 순서는 맵핑이나 코드에 있는 것으르 따른다.
  • 따라서 다음의 코드는 에러가 나지 않지만, 만약에 Entity를 먼저 add했으면 에러가 날 것이다.
List result = s.createSQLQuery("select o.*, o.value as anumber from ORDER as o").addScalar("anumber").addEntity(Order.class).list();
Object[] row = (Object[])result.get(0);
Integer number = (Integer)row[0];
Order order = (Order)row[1];

Stored procedures no longer require OUT parameter

  • 이전에는 영향을 받는 row의 수를 반환하는 out 파라미터를 필요로 했었는데 이젠 필수사항이 아니다.
  • check 속성에 none, count, param 을 사용할 수 있다.

Migrate To Hibernate 3.1

API 변경사항

NamingStrategy 인터페이스로 업데이트

  • 인터페이스에 추가된 새로운 메소드를 구현하거나, DefaultNamingStrategy 또는 ImprovedNamingStrategy 클래스를 상속받아라.

이벤트 리스너

  • 이벤트 하나에 여러 개의 리스너를 등록할 수 있다. 이벤트 리스너의 API들이 리스너 배열을 받도록 수정되었다.

설정 변경사항

JDBC 커넥션 release mode

  • 이전(2.0, 3.0)까지는 기본값이 ON_CLOSE였는데, 기본값이 이제(3.1)는 auto로 바꼈다.
  • session.connection()을 호출했을 때는 close()를 호출해야한다. 이 뒤에 배포에서 이 부분은 변경 될 것이다.

이벤트 리스너

  • 이벤트에 여러 개의 리스너를 등록할 수 있다.
  • hibernate.cfg.xml에서 <listener> 대신에 좀 더 정확한 <event> 엘리먼트를 사용한다.

쿼리 언어 변경사항

Stricter checking of invalid queries

  • from Entity e where e.collection.property 이런 쿼리는 작성할 수 없다. 명시적으로 join을 사용해야 한다.
  • fetch를 사용할 때, 주가 되는 쪽을 가져오지 않는 쿼리는 의미가 없으므로 예외를 발생시킨다. ex) select b from A join fetch a.bees b

hbm2java

  • 별도의 툴이 아니라, tools.hibernate.org에 통합됐다. 이 과정에서 깨지거나 유지보수 하지 않는 기능은 제거했다. Hbm2javaCompability을 참조하라.

Migrate To Hibernate 3.0

참조: Hibernate Migration Reference

API 변경사항

패키지 이름

  • net.sf.hibernate에서 org.hibernate로 변경.
  • net.sf.hibernate.expression에서 org.hibernate.criterion으로 변경.
  • 하이버네이트를 참조하는 외부 라이브러러(EHCache 같은 경우) net.sf.ehcache.hibernate.Provider에서 org.hibernate.cache.EhCacheProvider로 변경.

Deprected Interfaces

  • org.hibernate.classic 패키지로 이동됐다.
  • Session 인터페이스의 find(), iterate(), filter(), delete() 대신에 createQuery() 사용해야 된다.
  • Session 인터페이스의 saveOrUpdateCopy()대신에 delete, merge() 해야된다.
  • 배열을 인자로 받는 createSQLQuery()는 deperecated됐다.
  • Lifecycle과 Validatable 인터페이스는 deprecated됐다. 그 대신 Interceptor나 Hibernate 3 이벤트 프레임워크를 사용하라.

종속성

  • lib/README.txt 참조할 것.

예외 모델

  • HibernateExcpetion을 비롯해 모든 예외는 Uncheched Exception으로 바꼈다.

Interceptor 인터페이스

  • 두 개의 새로운 메소드 추가 됐다. 따라서 이 인터페이스 구현체들은 비어있는 메소드 두 개를 구현해야 한다.
  • instantiate()의 인자로 Class 객체 대신에 Entity 이름을 받는 String 값을 받도록 바꼈다.
  • isUnsaved())에서 isTransient()로 메소드 이름이 바꼈다.

UserType, CompositeUserType

  • org.hibernate.usertype 패키지로 이동됐고, 새로운 메소드 몇 개가 추가 됐다.
  • ParameterizedType 인터페이스 추가됐다.

FetchMode

  • FetchMode.Lazy와 FetchMode.EAGER는 deprecated됐다. 좀 더 정확한 이름으로 FetchMode.SELECT와 FetchMode.JOIN으로 바꼈다.

PersistentEnum

  • PersustentEnum 클래스는 Hibernate3에서 제거됐다. UserType을 사용하라.

Blob과 Clob 지원

  • Blob이나 Clob 타입을 detached, serialized, merge() 메소드에 넘길 수 있고,
    특정 밴더의 타입으로 다음과 같이 변환할 수도 있다. getWrappedClob(), getWrappedBlob() 사용한다.
clob = (oracle.sql.CLOB) ( (org.hibernate.lob.SerializableClob) foo.getText() ).getWrappedClob();

확장 API

  • org.hibernate.criterion, org.hibernate.mapping, org.hibernate.persister 그리고 org.hibernate.collection 패키지는 상당히 많이 리팩터링 했다.

Metadata 변경사항

Association Fetching 전략

  • lazy=”true”를 기본값으로 바꿨다. 따라서 이 설정을 하지 않은 클래스와 컬렉션에 모두 lazy=”false”를 붙여야 한다.
  • outer-join 속성이 deprecated됐다. outer-join=”true” 대신에 fetch=”join”, outer-join=”false” 대신에 fetch=”select”를 사용하라.

식별자 맵핑

  • unsaved-value=”0″을 기본값으로 사용한다.
  • 하이버네이트 3에서 natural
    key(assigned identifier 또는 복합키)를 사용하거나 detached 객체를 쓸 때, 더이상
    Interceptor.isUnsaved() 메소드를 구현할 필요가 없다. 힌트 없으면 DB에 쿼리 날려서 객체가 새로 만든
    것인지 detached 인지 알아낸다. 따라서 그냥 isUnsaved() 사용하는게 성능에 좋겠다.

콜렉션 맵핑

  • <index>는 준-deprecated 됐다. <list-index>와
    <map-key>를 권장한다. <key-many-to-many> 대신에
    <map-key-many-to-many>, <composite-index> 대신에
    <composite-map-key>를 사용하라.

DTD

Query Language Changes

  • 하이버네이트 3은 ANTLR-based HQL/SQL query translator를 사용한다. 2.1의 쿼리 파서도 사용할 수 있다.
  • 예전 쿼리 파서를 사용하려면 hibernate.query.factory_class 속성에 org.hibernate.hql.classic.ClassicQueryTranslatorFactory
  • 새로운 파서를 사용하려면, org.hibernate.hql.ast.ASTQueryTranslatorFactory를 설정한다.
  • Note:
    there is a known bug affecting dialects with theta-style outer joins
    (eg. OracleDialect for Oracle 8i, TimesTen dialect, Sybase11Dialect).
    Try to use a dialect which supports ANSI-style joins (eg.
    Oracle9Dialect), or fall back to the old query parser if you experience
    problems.
  • elements() 대신에 명시적인 join을 사용하라.

설정 변경

  • BEA Weblogic issues 패스.