11.2.1. 非托管环境

如果Hibernat持久层运行在一个非托管环境中,数据库连接通常由Hibernate的简单(即非DataSource)连接池机制 来处理。session/transaction处理方式如下所示:

//Non-managed environment idiom
Session sess = factory.openSession();
Transaction tx = null;
try {
    tx = sess.beginTransaction();

    // do some work
    ...

    tx.commit();
}
catch (RuntimeException e) {
    if (tx != null) tx.rollback();
    throw e; // or display error message
}
finally {
    sess.close();
}

你不需要显式flush() Session - 对commit()的调用会自动触发session的同步(取决于session的第 10.10 节 “Session刷出(flush)”)。调用 close() 标志session的结束。close()方法重要的暗示是,session释放了JDBC连接。这段Java代码在非托管环境下和JTA环境下都可以运行。

更加灵活的方案是Hibernate内置的"current session"上下文管理,前文已经讲过:

// Non-managed environment idiom with getCurrentSession()
try {
    factory.getCurrentSession().beginTransaction();

    // do some work
    ...

    factory.getCurrentSession().getTransaction().commit();
}
catch (RuntimeException e) {
    factory.getCurrentSession().getTransaction().rollback();
    throw e; // or display error message
}

你很可能从未在一个通常的应用程序的业务代码中见过这样的代码片断:致命的(系统)异常应该总是 在应用程序“顶层”被捕获。换句话说,执行Hibernate调用的代码(在持久层)和处理 RuntimeException异常的代码(通常只能清理和退出应用程序)应该在不同 的应用程序逻辑层。Hibernate的当前上下文管理可以极大地简化这一设计,你所有的一切就是SessionFactory。 异常处理将在本章稍后进行讨论。

请注意,你应该选择 org.hibernate.transaction.JDBCTransactionFactory (这是默认选项),对第二个例子来说,hibernate.current_session_context_class应该是"thread"