在 Visual Web JSF 应用程序中使用 Hibernate
由 NetBeans 中文社区的 Solaris_navi 更新翻译
在本教程中,您将使用 NetBeans IDE 来创建和部署显示数据库中数据的 Web 应用程序。在检索简单传统 Java 对象(Plain Old Java Object, POJO)和将其存储到关系数据库中时,Web 应用程序将使用 Hibernate 框架作为持久性层。
Hibernate 是一个为对象关系映射 (ORM) 提供工具的框架。本教程将演示如何向 IDE 添加对 Hibernate 框架的支持以及如何添加必需的 Hibernate 文件。创建 Java 对象并将应用程序配置为使用 Hibernate 之后,向 Web 页中添加 Visual Web JSF 组件以显示数据。
在开始本教程之前,您可能需要先熟悉如何使用 Hibernate 和 Visual Web JSF 组件。
您可以从 适用于 NetBeans IDE 的 Hibernate 演示观看该教程的视频。
目录

学习本教程,您需要具备以下软件和资源。
您可以从插件门户网站的 Hibernate Travel 应用程序插件页 下载本教程使用的解决方案。
创建 Web 应用程序项目
在本练习中,您将创建一个 Visual Web JSF 项目并在其中添加 Hibernate 库。创建项目之后,您将在“新建项目”向导的“框架”面板中选择 "Visual Web JSF" 和 "Hibernate"。您还将指定数据库。 当您创建项目时 IDE 自动添加所需的库。
- 选择“文件” > “新建项目”(Ctrl-Shift-N)。从 "Web" 类别中选择“Web 应用程序”并单击“下一步”。
- 键入 HibernateTravelApp 作为项目名称并设置项目位置。
- 取消选中“使用专用的文件夹来存储库”选项(如果该选项处于选中状态)。
对于本教程,没有必要将项目库复制到专用文件夹,因为您不需要与其他用户共享库。
单击“下一步”。
- 将“服务器”设置为 “GlassFish V2“,并将“Java EE 版本”设置为 "Java EE 5"。单击“下一步”。
- 选中“Visual Web JavaServer Faces”复选框。
- 选中“Hibernate 3.2.5”复选框 并在“数据库连接”的下拉菜单中选择“Travel”数据库。单击”完成“。
注意: IDE 附带一个样例 Travel 数据库以及一个到该数据库的预配置的连接。如果在向导的“框架”面板中,Travel 数据库未作为一个可用选项,则检查“服务”窗口中的“数据库”节点下是否列出了该连接。如果此处没有该连接,则需要创建数据库连接。
单击“完成”后,IDE 将创建 Web 应用程序项目并在编辑器中打开 hibernate.cfg.xml 文件和 Page1 。
如果您展开“项目”窗口中的“库”节点,可以看到 IDE 已向项目中添加了 Hibernate 库。
修改 Hibernate 配置文件
创建使用 Hibernate 框架的新项目时,IDE 会自动在应用程序的上下文类路径的根路径(“文件”窗口中的 Web-INF/classes)上创建 hibernate.cfg.xml 配置文件。 在“项目”窗口中您可以在 <default packages> 源包中看到这个文件。 该配置文件包含关于数据库连接、资源映射和其他连接属性的信息。 您可以使用多视图编辑器编辑该文件或直接在 XML 编辑器中编辑 XML。
在本练习中,您将编辑在 hibernate.cfg.xml 中指定的缺省属性,以启用 SQL 语句的调试日志记录以及 Hibernate 的会话上下文管理。
- 在“设计”标签中打开 hibernate.cfg.xml 。
您可以通过在“项目”窗口中展开 <default packages> 源包并双击 hibernate.cfg.xml来打开该文件。
- 在“可选属性”下,展开“配置属性”节点。
- 单击“添加”以打开“添加 Hibernate 属性”对话框。
- 在此对话框中,选择 hibernate.show_sql 属性并将值设置为 true。 这将启用 SQL 语句的调试日志记录。

- 展开“其他属性”节点并单击“添加”。
- 在对话框中,选择 properties hibernate.current_session_context_class 属性并将其值设置为 thread 以启用 Hibernate 的自动会话上下文管理。
如果单击编辑器中的 XML 标签,则可以在 XML 视图中看到此文件。该文件应该如下所示:
<hibernate-configuration>
<session-factory name="session1">
<property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
<property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
<property name="hibernate.connection.url">jdbc:derby://localhost:1527/travel</property>
<property name="hibernate.connection.username">travel</property>
<property name="hibernate.connection.password">travel</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
- 保存对该文件所做的更改。
生成 Hibernate 映射文件以及 Java 类
在本教程中,您将使用两个简单传统 Java 对象(Plain Old Java Object, POJO) Person 和 Trip, 来呈现 travel 数据库中的表 PERSON 和 TRIP 中的数据。 每个类为表中的列指定字段并使用简单的 setter 和 getter 检索和编写数据。 每个 POJO 拥有一个相应的 Hibernate 映射文件。 Hibernate 映射文件是一个 XML 文件,包含了定义类如何映射到数据表中的列(Column)和主键(Primary Key)的 ORM(对象关系映射,Object Relational Mapping)的元数据。当您使用向导从数据库中生成 POJO 以及相应的映射文件时,IDE 为每一个类和映射数据生成一个映射文件。
在本教程中您将在“数据库”向导中使用 Hibernate 映射文件以及 POJO 用来创建基于您所选数据库的数据表的多个 POJO 以及映射文件。 如果您希望 IDE 的向导能帮助您重新生成每一个 POJO及其映射文件, 您可以在 XML 编辑器中编辑映射文件,然后使用 IDE 的代码自动完成功能来帮助您将这些字段映射到表的列上。
Hibernate 映射文件与来自数据库的 POJO 向导基于数据库生成文件。 当您使用向导时您可以选择所有您想要的 POJO 和映射文件的数据表,其后,IDE 将根据数据表生成文件并添加映射到 hibernate.cfg.xml 中。 当您使用向导时您可以选择您想要 IDE 生成的文件(例如,仅生成 POJO),以及选择代码生成选项(例如,使用 EJB 3 的说明或定义生成代码)。
- 在“项目”窗口中右键单击“源包”节点,选择“新建” > “其他”,打开“新建文件”向导。
- 从“Hibernate 类别”列表中选择 Hibernate 映射文件与来自数据库的 POJO。单击“下一步”。
- 在“名称与位置”面板中保留默认值。单击“下一步”。
- 从“配置文件”下拉菜单中选择 hibernate.cfg.xml。(如果 hibernate.cfg.xml 未被选择)。
- 从可用数据表中选择 person 以及 trip,并单击“添加”将数据表添加到“已选数据表”中。 单击“下一步”
- 保证 Domain Code 与 Hibernate XML Mappings 选项处于被选状态。
- 键入 travel 为源包的名称。单击“完成”。
当您单击“完成”时,如果您展开 travel 包您可以看到 IDE 为 PERSON 和 TRIP 表创建了 POJO,并位每一个 POJO 创建了 Hibernate 映射文件。 如果您打开 Hibernate 配置文件(hibernate.cfg.xml)您可以看到 IDE 同时为映射文件添加了映射资源。
如果您在编辑器中打开 Person.java,您可以看到 IDE 根据表中的列生成的字段。 IDE 同时为字段生成了 getter 与 setter 方法。
public class Person implements Serializable {
private int personid;
private String name;
private String jobtitle;
private Short frequentflyer;
private Date lastupdated;
private java.util.Set trips;
}
如果您在编辑器中打 Person.java 的开映射文件 Person.hbm.xml,您可以看到 IDE 为这个类生成了如下映射信息。
<hibernate-mapping>
<class name="travel.Person" table="PERSON" schema="TRAVEL">
<id name="personid" type="int">
<column name="PERSONID" /">
<generator class="assigned"/>
</id>
<property name="name" type="string">
<column name="NAME" length="50" />
</property>
<property name="jobtitle" type="string">
<column name="JOBTITLE" length="50" />
</property>
<property name="frequentflyer" type="java.lang.Short">
<column name="FREQUENTFLYER" />
</property>
<property name="lastupdated" type="timestamp">
<column name="LASTUPDATED" length="26" />
</property>
<set cascade="all-delete-orphan" inverse="true" lazy="true" name="trips" table="TRIP">
<key column="PERSONID"/>
<one-to-many class="travel.Trip"/>
</set>
</class>
</hibernate-mapping>
您可以打开 Travel.java 以及 Travel.hbm.xml 来看向导生成的代码。
注意: 如果您使用“Travel”数据库的 Java DB 版本, 您需要手动添加如下代码来添加生成 POJO Person.java 及其映射信息的 Hibernate 映射文件的关系字段。
- 添加 private java.util.Set trips; 到 Person.java 中并修复您的导入(import)文件。
- 为字段 trips 生成 getter 与 setter 方法 (Ctrl-I)。
- 添加下面的映射信息(粗体)到 Person.hbm.xml 中。
</property>
<set cascade="all-delete-orphan" inverse="true" lazy="true" name="trips" table="TRIP">
<key column="PERSONID"/>
<one-to-many class="travel.Trip"/>
</set>
</class>
</hibernate-mapping>
更多关于当使用 Java DB 时关系字段无法生成的问题, 请参看 问题 148836。
创建 Hibernate Helper 类
要使用 Hibernate,您需要创建一个 helper 类,该类处理启动并访问 Hibernate 的 SessionFactory 来获得 Session 对象, 以便您可以加载和存储 Person 和 Trip 对象。此 helper 类首先调用 Configuration() 来加载 hibernate.properties 文件。 然后,该类调用 configure() 并加载 hibernate.cfg.xml 配置文件。 最后,此 helper 类构建 SessionFactory 来获得 Session 对象。
在本节中,使用“新建文件”向导创建 helper 类 HibernateUtil.java。
- 右键单击 travel 源包节点并选择“新建” > “其他”以打开“新建文件”向导。
- 从“类别”列表中选择 Hibernate,从“文件类型”列表中选择 HibernateUtil.java。单击“下一步”。
- 键入 HibernateUtil 作为类名并选择 travel 包。 单击“完成”。

单击“完成”后,该类将在编辑器中打开。 由于不需要编辑该文件,因此可以关闭该文件。
现在,您已经拥有应用程序所需的所有类。在“项目”窗口中展开“源包”节点,您的项目应该与下图类似。
创建 Visual Web JSF 页
创建类之后,可以创建用于显示和修改数据的 Web 页。您将创建一个使用 JSF 框架和绑定到对象的 Visual Web JSF 组件的 JSP 页。
向页中添加 Visual Web JSF 组件
- 在“项目”窗口中,展开“Web 页”文件夹并在“可视设计器”中打开 Page1.jsp 。
- 从组件面板的“Woodstock 基本”组件集中拖放一个“下拉列表”组件到 Page1 的左上角。
- 右键单击“下拉列表”组件,并从弹出式菜单中选择“更改时自动提交”。
当用户从下拉列表中选择新值时,该操作就会让浏览器提交该页面。
- 再次右键单击“下拉列表”组件并选择“添加绑定属性”
注意: 您将在本教程稍后的部分中指定属性绑定。NetBeans IDE 6.1 与 6.5 具有按需绑定功能。 在组件需要 Java 编码的位置,必须手动为 Visual Web JSF 应用程序中的组件添加绑定属性。 要执行此操作,右键单击各组件,然后选择“添加绑定属性”。有关详细信息,请参见 On-demand Binding Attribute Wiki(按需绑定属性 Wiki)。
现在,您的 Web 页已具备了必要的组件。现在,需要将这些组件绑定到数据源。
从 SessionBean1 访问数据源
现在,您需要编辑 SessionBean1 以访问数据源。 在本练习中,您将使用“添加属性”对话框指定 SessionBean1 中的字段并为这些字段生成 getter 和 setter。 会话 Bean 将打开一个会话上下文,然后通过 Java 对象检索数据。
- 在“项目”窗口中,展开 hibernatetravelapp 源包并双击 SessionBean1.java 以在编辑器中打开该文件。
- 将光标放置在源代码中的空白区域(例如,构造函数后面),单击鼠标右键并选择“插入代码” > “添加属性”(Ctrl-I) 以打开“添加属性”对话框。
- 在“添加属性”对话框中,在“名称”字段中键入 personOptions ,在“类型”字段中键入 Option[] 并选择 private。
- 选择“生成 Getter 和 Setter”(如果为未选中状态)。单击“确定”。

- 重复这些步骤,添加以下属性:
| selectedPersonId |
Integer |
| trips4Person |
Trip[] |

- 通过在 getApplicationBean1 方法之后向 SessionBean1 中添加以下内容(粗体)向类中添加 buildPersonOptions 和 updateTrips4Person 方法。
protected ApplicationBean1 getApplicationBean1() {
return (ApplicationBean1) getBean("ApplicationBean1");
}
private void buildPersonOptions() {
List<Person> personList = null;
try{
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
Query q = session.createQuery("from Person");
personList = (List<Person>) q.list();
} catch(Exception e) {
e.printStackTrace();
}
personOptions = new Option[personList.size()];
int i=0;
for(Person person : personList) {
Option opt = new Option(person.getPersonid(), person.getName());
personOptions[i++] = opt;
}
}
private void updateTrips4Person() {
if(selectedPersonId == null ) {
trips4Person = new Trip[1];
trips4Person[0] = new Trip();
return;
}
Set personTrips = null;
try{
Session session =
HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
Person person = (Person)session.load(Person.class, selectedPersonId);
personTrips = (PersistentSet)person.getTrips();
} catch(Exception e) {
e.printStackTrace();
}
trips4Person = (Trip[]) personTrips.toArray(new Trip[0]);
}
buildPersonOptions 方法调用对 Person 数据源的查询并将结果存储在 personOptions 数组中。 updateTrips4Person 方法更新所选个人的行程。
- 修复导入。
注意:选择要导入的完全限定名称时, 请确保选择 org.hibernate 库以及 com.sun.Webui.jsf.model.Option 和 java.util.Set。
- 通过在 init() 方法的末尾添加以下内容(粗体)来调用 buildPersonOptions 方法。
@Override
public void init() {
super.init();
try {
_init();
} catch (Exception e) {
log("SessionBean1 Initialization Failure", e);
throw e instanceof FacesException ? (FacesException) e : new FacesException(e);
}
// Fill in the personOptions[]
buildPersonOptions();
}
- 通过在 setSelectedPersonId 方法的末尾添加以下内容(粗体)来调用 updateTrips4Person 方法。
public void setSelectedPersonId(Integer selectedPersonId) {
this.selectedPersonId = selectedPersonId;
updateTrips4Person();
}
- 保存所做的更改。
- 在“项目”窗口中右键单击项目节点,并选择“构建”。
将组件绑定到数据
在本节中,将 Web 页中的“下拉列表”和“表”组件绑定到 SessionBean1 中在上一部分定义的属性。
- 在“可视设计器”中打开 Page1.jsp。
- 右键单击“下拉列表”组件并选择“属性绑定”以打开“属性绑定”对话窗口。
- 在可绑定的属性列表中选择“项目”并在绑定目标列表中选择 personOptions(位于 SessionBean1 节点下)。 单击“应用”。

- 在同一对话框中,在可绑定的属性列表中选择“选定”并在绑定目标列表中选择 selectedPersonId(位于 SessionBean1 节点下)。 单击“应用”。

- 单击“关闭”关闭此对话窗口。
- 在可视设计器中,右键单击“表”组件并选择“表布局”。
- 在该对话框中,从“数据来自”下拉列表中选择 trips4Person (SessionBean1)。
注意:如果在下拉列表中没有看到 trips4Person (SessionBean1),则很可能是因为您忘记了在上一部分结束时构建该项目。
- 在“选定”列表中选择 personId 并单击向左箭头按钮将该字段从“选定”列表移动到“可用”列表中。
- 使用“上移”和“下移”按钮按以下顺序排列剩余的字段,如下所示,然后单击“确定”。

- 在“编辑”工具栏中,单击 Java 以在 Java 编辑器中打开 Page1.java。
- 在 prerender 方法中,添加以下代码(以粗体显示的内容)。
public void prerender() {
try {
if (dropDown1.getSelected() == null ) {
Option firstPerson = getSessionBean1().getPersonOptions()[0];
getSessionBean1().setSelectedPersonId((Integer)firstPerson.getValue());
}
} catch (Exception ex) {
log("Error Description", ex);
error(ex.getMessage());
}
}
prerender 方法中的代码将在 Web 浏览器开始显示页面之前调用。 向 prerender 方法中添加代码会使该页在用户第一次访问页面时在下拉列表中显示第一个人的信息。
当浏览器首次请求此页面时,应用程序会创建 Page1 的一个实例并调用 prerender 方法。 服务器将发送响应(HTML 页面),并且 Page1 实例将被破坏。 应用程序并不会调用值更改事件处理程序,因为应用程序只有在提交页面时(在本例中,选择一个新的个人时)才会生成值更改事件。
- 右键单击源代码并从弹出式菜单中选择“修复导入”以打开“修复导入”对话框。 在“全限定名称”下拉列表中,选择 com.sun.Webui.jsf.model.Option,如下所示。

- Save your changes.
运行项目
-
在主工具栏中单击“运行主项目”。
IDE 将保存所有修改的文件,重新生成应用程序并将其部署到服务器中。
- 从下拉列表中选择某个人,查看表的内容如何随所选个人的数据一起更新。

安装示例插件
您可以通过从插件门户网站下载 Hibernate Travel 应用程序插件来下载本教程使用的解决方案项目。 在安装插件后,一个样例项目将添加到“新建项目”向导中的可用 Visual Web 样例中。 您必须先将 Hibernate 和 JSF 库添加到项目中,然后才能运行样例应用程序。 您还需要向 IDE 注册一个 Glassfish 应用服务器实例。
您需要安装 Hibernate 插件,然后才能向项目添加 Hibernate 库。
请完成下列步骤以下载插件,创建样例项目并添加必需的 Hibernate 和 JSF 库。
- 选择“工具”>“插件”以打开插件管理器。
- >在“可用插件”标签中选择 “Hibernate Travel App Sample”。 单击“安装”。
单击安装后,按照插件安装程序的说明一步步执行插件安装。
当看到有关样例应用程序插件未签名的警告时,单击“继续”。
- 从主菜单中选择“文件” > “新建项目”以打开“新建项目”向导。
- 在“类别”窗格中,选择“样例” > “Web” >“ Visual JSF” ,然后选择 “Hibernate Travel App Sample”。单击“下一步”。
- 指定项目位置。单击“完成”。
单击“完成”时,IDE 将创建该项目并在“项目”窗口中显示该项目。 项目将无法正常编译,因为缺少某些库。 在“项目”窗口中展开该项目的“库”节点,您可以看到缺少必需的 Hibernate 和 JSF 库。

- 右键单击“库”节点并从弹出式菜单中选择“添加库”。 “添加库”对话框将显示可用的库。
- 单击“导入”打开“导入库”对话框。
- 选择以下全局库:
- Hibernate
- JSF 1.1/1.2 支持
- Web UI 组件
- Web UI 缺省主题
在选择库时,可以通过按住 ctrl 键选择多个库。
单击“导入库”。
- 确保在“添加库”对话框中选择了正确的库,然后单击“添加库”。
当您单击“添加库”时,IDE 会在“项目”窗口的“库”节点下显示已添加的库。
在添加了必需的库后,您的源文件上的编译错误标记将消失。
- 右键单击项目节点,然后选择“运行”。
单击“运行”,IDE 将生成应用程序并将应用程序部署到服务器。 缺省的 Web 页将在浏览器窗口中打开。
另请参阅