第 1 章 创建一个注解项目

1.1. 系统需求

  • 首先从Hibernate官方网站下载并解压Hibernate Annotations的发布包。

  • 这个版本(预览版)要求使用Hibernate 3.2.0.CR2或更高版本。请不要和老版本的Hibernate 3.x混合起来使用。

  • 这个版本在Hibernate core 3.2.0.CR2的基础上工作良好。

  • 首先确定你已经安装了JDK 5.0。当然就算使用低版本的JDK, Xdoclet也可以提供(基于注解的)元数据所带来的部分功能。 不过请注意本文档只描述跟JDK5.0注解有关的内容,关于Xdoclet请参考相关文档。

1.2. 系统配置

首先就是设置classpath(当然是在IDE中创建了一个新项目之后)。

  • 将Hibernate3核心文件以及其依赖的第三方库文件(请参考lib/README.txt文件)加入到你的classpath里面。

  • hibernate-annotations.jarlib/ejb3-persistence.jar加入到你的classpath里面。

  • 如果要使用 第 5 章 Hibernate与Lucene集成,还需要将lucene的jar文件加入你的classpath。

我们推荐在一个包装器(wrapper)类HibernateUtil 的静态初始化代码块中启动Hibernate。或许你在Hibernate文档的其他很多地方看到过这个类, 但是要在你的项目中使用注解,还需要对这个辅助(helper)类进行扩展。扩展如下:

package hello;

import org.hibernate.*;
import org.hibernate.cfg.*;
import test.*;
import test.animals.Dog;

public class HibernateUtil {

private static final SessionFactory sessionFactory;

    static {
        try {

            sessionFactory = new AnnotationConfiguration().buildSessionFactory();
        } catch (Throwable ex) {
            // Log exception!
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static Session getSession()
            throws HibernateException {
        return sessionFactory.openSession();
    }
}
            

这里比较有意思的是使用到了AnnotationConfiguration类。 在XML配置文件(通常是hibernate.cfg.xml)中则定义了包和经过注解的类。下面的xml和前面的声明等价:

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

        <hibernate-configuration>
          <session-factory>
            <mapping package="test.animals"/>
            <mapping class="test.Flight"/>
            <mapping class="test.Sky"/>
            <mapping class="test.Person"/>
            <mapping class="test.animals.Dog"/>
            <mapping resource="test/animals/orm.xml"/>
          </session-factory>
        </hibernate-configuration>
        

注意现在你可以混合使用hbm.xml和注解。资源元素(resource element)可以是hbm文件也可以是EJB3 XML发布描述符,此差别对于配置过程是透明的。

除了上面的方式,你还可以通过编程的方式定义包括注解的类和包

            sessionFactory = new AnnotationConfiguration()
                    .addPackage("test.animals") //the fully qualified package name
                    .addAnnotatedClass(Flight.class)
                    .addAnnotatedClass(Sky.class)
                    .addAnnotatedClass(Person.class)
                    .addAnnotatedClass(Dog.class)
                    .buildSessionFactory();

你也可以使用Hibernate Entity Manager来完成以上功能。Hibernate Entity Manager有自己的一套配置机制,详情请参考相关文档。

除了启动方式和配置文件有所改变之外,结合注解来使用Hibernate API和以前没有什么区别, 在其他方面你还是可以继续保持以前的习惯和喜好(hibernate.propertieshibernate.cfg.xml, programmatic APIs等等)。 甚至对于同一个SessionFactory,你都可以混合带注解的持久类以及传统的bm.cfg.xml声明方式。 然而你不能多次声明同一个类(要么通过注解要么通过hbm.xml配置文件), 而且在一个映射实体的类继承层次中,这两个配置策略不能同时使用.

为了简化从hbm文件到注解的迁移过程, 配置机制将自动检测在注解和hbm文件中重复的映射。 默认情况下hbm文件中的声明比类中的注解元数据具有更高的优先级。 这种优先级的设定是以类为单位的。 你也可以通过hibernate.mapping.precedence修改这种优先级。 默认的值是hbm, class, 如果改为class,hbm,当发生冲突的时候,类中的注解将比hbm文件具有更高的优先级。