技术开发 频道

如何构建 EJB 3.0 应用程序

  高级 EJB 功能

  EJB 3.0 在不影响功能的情况下提供了简单的编程模型。基本原则是使用缺省值,仅在必要时才使用其他值覆盖缺省值。例如,EJB 3.0 仍允许 XML 配置。XML 部署描述符可以覆盖注释,因此,您可以针对不同的部署环境外部化配置并覆盖设置。在本部分中,您将继续使用注释,但是将向该应用程序添加更多功能,以便了解 EJB 3.0 的一些其他特征。(此处使用的应用程序是专门为说明不同的 EJB 3.0 和 JPA 功能而设计的,而不是作为应用程序设计非常好的实践的一个示例。)

  本部分的操作步骤包括:

  构建 JPA 对象

  构建另一个会话 Bean

  添加拦截器

  测试应用程序

  A. 构建 JPA 对象

  以下步骤介绍了如何使用 JPA Eclipse 工具来生成更多 JPA POJO,然后将更新映射,以针对用例进行自定义。

  JPA Eclipse 工具支持自顶向下、中间相遇、自底向上映射。您将使用自底向上工具来生成其余的实体:

  在 Package Explorer 视图中,右键单击 OrderSystemEJB 并选择 Java Persistence => Generate Entities(图 65)。

  图 65. 生成实体

  选择您的连接(您的数据库连接现在可能已关闭;必要时请选择 Reconnect 链接并再次输入您的凭据),然后选择 CUSTSCH 模式。按 Next(图 66)。

  图 66. 选择连接和模式

  在 Generate Entities from Tables 面板上,仅选择 LINEITEM、CUSTORDER 和 PRODUCT。确保您的 Package 名称为 com.ibm.ejb3.order.entities。由于 CUSTORDER 表名称不同于实体名称(“Order”,这是该实体所需的名称),因此请输入 Order 作为 CUSTORDER 的实体名称(图 67)。单击 Finish。

  图 67. 选择表

  接下来将更新这些映射:

  打开 Order 实体(图 68)。

  图 68. 检查 Order 类

  使用 Java Persistence Properties Editor 或添加以下用粗体标记的注释:

  需要使用 @Table 注释来覆盖该模式名称。

  @NamedQuery 将向您的 JPA POJO 添加一个查询。JPA 有非常丰富的查询语言可供您使用,即 EJB-QL。此查询将向该客户询问开放订单。

  与您前面的操作相同,必须将订单属性注释为 ID。另外,您将添加标识的生成策略。

  最后,请注意 Order 与 LineItems 有关系。您需要添加 Eager 的获取规则。这意味着,当有人请求订单时,JPA 引擎还将获取与该订单相关的所有行项目。

1 @Entity
2
3   @Table(name="CUSTORDER", schema="CUSTSCH")
4
5   @NamedQuery(name="getCurrentOrder",
6
7   query="select o from Order o where o.customerId = :customerId and
8
9   o.status ='OPEN'")
10
11   public class Order implements Serializable {
12
13   @Id
14
15   @Column(name="ORDER_ID")
16
17   @GeneratedValue(strategy=GenerationType.IDENTITY)
18
19   private int orderId;
20
21   private String status;
22
23   private double total;
24
25   @Column(name="CUSTOMER_ID")
26
27   private int customerId;
28
29   @OneToMany(mappedBy="orderId",fetch=FetchType.EAGER)
30
31   private Set lineitemCollection;
32
33

  您需要更新该 Customer 实体,使之与 Order 关联。系统要求 Customer 仅有一个开放订单。您需要创建与该开放订单的关系。由于一个 Customer 有许多订单,因此您不需要生成该关系,但当该客户仅有一个开放订单时则需要生成该关系。

  打开 Customer 实体。如以下代码所示,添加 Order currentOrder。使用 Eclipse Java 工具生成 setters 和 getters。

1 package com.ibm.ejb3.order.entities;
2
3 import java.io.Serializable;
4 import javax.persistence.Entity;
5 import javax.persistence.Id;
6 import javax.persistence.GeneratedValue;
7 import javax.persistence.GenerationType;
8 import javax.persistence.Column;
9 import javax.persistence.Table;
10
11 @Entity
12 @Table(name="CUSTOMER", schema="CUSTSCH")
13 public class Customer implements Serializable {
14     
15     @Id
16     @GeneratedValue(strategy=GenerationType.IDENTITY)
17     @Column(name="CUST_ID")
18     private int customerId;
19     private String name;
20     
21     
22 private Order currentOrder;
23     
24     public int getCustomerId() {
25         return customerId;
26     }
27     public void setCustomerId(int customerId) {
28         this.customerId = customerId;
29     }
30     public String getName() {
31         return name;
32     }
33     public void setName(String name) {
34         this.name = name;
35     }
36     public Order getCurrentOrder() {
37         return currentOrder;
38     }
39     public void setCurrentOrder(Order currentOrder) {
40         this.currentOrder = currentOrder;
41     }
42
43 }

  如下所示,添加以下 @OneToOne 和 @JoinColumn 注释。

  注意,该获取规则被设置为 Lazy,所以当有人查询该客户时,您将不获取该订单。

  您已经设置某些级联规则。如果有人更新该开放订单,更改将按照定义级联。

  该关系是可选的,这意味着,该客户并不能始终拥有开放订单。

  您已经指定了 Join 列(该名称与 Customer 表上的外键对应,而 referencedColumn 名称与 Custorder 表的主键对应。)如果您未指定 Join 列,JPA 将根据命名方案尝试解析这些键。

1 @OneToOne(fetch=FetchType. LAZY,cascade =
2     {CascadeType.MERGE,CascadeType.REFRESH},optional=true )
3     
4 @JoinColumn(name="OPEN_ORDER_ID",referencedColumnName="ORDER_ID")
5 private Order currentOrder;

  像处理 Customer 和 Order 那样,更新 LineItem 类以指向正确的模式(图 69)。

  图 69. LineItem 模式

  类似地,覆盖产品模式(图 70)。

  图 70. 产品模式

  保存并关闭实体。

 

0
相关文章