| | | |
Sun ONE Application Server 7 Enterprise Java Bean 开发者指南 |
将容器管理持久性用于实体 Bean本节包含在 Sun ONE Application Server 7 环境中容器管理持久性工作方式的信息。同时包含实施步骤。
注意 要实施容器管理持久性,应先熟悉实体 Bean。实体 Bean 在“使用实体 Bean”中讲述。
本节介绍以下主题:
有关容器管理持久性的详细信息,请参阅 Enterprise JavaBeans Specification 2.0 第 10、11 和 14 章。
Sun ONE 应用服务器支持
Sun ONE 应用服务器对容器管理持久性的支持包括:
- 完全支持 J2EE 1.3 规范的容器管理持久性模型。
- 支持 Enterprise JavaBeans Specification 2.0 中定义的事务的 commit 选项 B 和 C。.有关详细信息,请参阅“Commit 选项”。
- 主键类必须是 java.lang.Object 的子类。这可确保可移植性,而且值得注意,因为有些供应商允许把基元类型(如 int)列为主键类。
- Sun ONE 应用服务器容器管理持久性实现,这包括:
- 对象/关系 (O/R) 映射工具(Sun ONE 应用服务器组装工具的组成部分),该工具为 EJB JAR 文件创建 XML 部署描述符,而 EJB JAR 文件包含使用容器管理持久性的 Bean。
- 支持复合(多列)主键
- 支持复杂自定义查找程序方法
- 基于标准的查询语言 (EJB QL)
- 容器管理持久性运行时,支持以下 JDBC 驱动程序/数据库:
- 支持第三方对象对关系 (O/R) 映射工具。有关第三方 API 的说明,请参阅“第三方可插拔持久性管理器 API”。
关于容器管理持久性
使用容器管理持久性的实体 Bean 将其状态(或持久性)管理委托给 Sun ONE 应用服务器容器。实施容器管理持久性的开发者不是编写实施容器管理持久性所需的 JDBC 代码,而是使用工具创建 Bean 的部署描述符。然后,部署描述符提供容器用以将 Bean 字段映射到关系数据库中列的信息。
EJB 容器需要两个条件才能支持容器管理持久性:
本节介绍以下容器管理持久性主题:
CMP 组件
与 bean 管理持久性不同的是,容器管理持久性不需要您在实体 Bean 类的方法中编写数据库访问调用。由于持久性是在运行时由容器处理的,您必须在部署描述符中指定容器必须针对其处理数据访问的那些持久性字段和关系。您使用为抽象持久性架构定义的访问程序方法访问持久性数据。
使用容器管理持久性的实体 Bean 包含多个可互操作的组件:
- 抽象 Bean 类,由您编写。
- 远程接口,由您编写。
- 本地接口,由您编写。
- 部署描述符,由您编写。
- 可选主键类,由您编写。
- 具体 Bean 类,通过容器管理持久性实现生成。
- 具体远程 Bean 实施类,通过容器管理持久性实现生成。
- EJBObject(skeleton),通过容器管理持久性实现生成。
- 远程stub,通过容器管理持久性实现生成。
以下类用于容器管理持久性:
关系
注意 只有在您使用容器管理持久性 2.0 Bean 时,本节才适用。
关系使您可以从一个对象导航到其相关对象。关系可以是双向的,也可以是单项的。
- 双向 - 每个实体 Bean 都具有一个引用另外那个 Bean 的关系字段。通过关系字段,实体 Bean 的代码可以访问其相关对象。如果某个实体 Bean 具有某个关系字段,我们通常说该实体 Bean“了解”其相关对象。
- 单向 - 只有一个实体 Bean 具有引用其他实体 Bean 的关系字段。
注意 即使关系是单向的,如果您对该关系进行更改,而且如果其他 Enterprise Bean 与该关系关联,也会影响这些 Enterprise Bean。
在一对类中通过字段来表示的容器管理持久性关系 (CMR), 允许在关系一端的操作可以影响另一端。运行时,如果修改一个实例中的字段来引用另一个实例,引用的实例将修改的关系字段来反映这个关系中的更改。
注意 如果您删除某个关系中的一个对象,不会收到警告。容器管理持久性会自动地在外键这端将关系设为空值,并在不请求确认的情况下删除对象。
在 Java 代码中,根据不同关系的种类,用对象引用( EJB 本地接口类型的集合或字段)表示关系。关系可以是一对一、一对多或多对多关系,具体情况取决于数据库中关系中每个类的实例数目。在数据库中,这可能由外键列表示,而且,如果是多对多关系,还可能联接表。
以下各节讲述各种关系类型:
一对一关系
如果是一对一关系,每个类中有一个单值字段,其类型是另一个类型的本地接口。对关系任何一端的字段的任何更改都会被作为关系更改进行处理。如果将一端的字段从 null 更改为non-null,则另一端的字段将更改为引用此实例。如果另一端的字段已经为 non-null,更改之前,会先将另一端的关系设置为空。
一对多关系
如果是一对多关系,多端上存在单值字段,一端上存在多值字段(集合)。
如果将一个实例添加到集合字段,就会更新新实例中的字段来引用包含集合字段的实例。如果从集合删除一个实例,就会清空实例中的字段。
更改、添加或删除多端上字段会被视为关系更改进行处理。将多端上字段从空更改为非空,就会把此实例添加到一端上的集合值字段。如果将多端上的字段从非空更改为空,就会从一端上的集合值字段中删除此实例。
多对多关系
如果是多对多关系,关系两端都存在多值或集合字段。对关系任何一端上集合内容的任何更改都会被作为关系更改进行处理。如果向此端上的集合添加实例,则会将此实例添加到另一端的实例。如果从此端的集合中删除一个实例,则会从另一端的集合中删除此实例。
抽象Schema
作为实体 Bean 的部署描述符的组成部分,抽象Schema定义 Bean 的持久性字段和关系。术语“抽象”将此schema与基本数据存储区的物理schema区别开来。
您在部署描述符中指定抽象Schema的名称。此名称由用 EJB 查询语言 (EJB QL) 编写的查询进行引用。.对于使用容器管理持久性的实体 Bean,您必须为每个查找程序方法(findByPrimaryKey 除外)定义 EJB-QL 查询。调用查找程序方法时,EJB-QL 查询确定 EJB 容器执行的查询。
示例
<ejb-relation>
<ejb-relation-name>OrderLineItem</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>
OrderHasLineItems
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>Order</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>lineItems</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>
LineItemInOrder
</ejb-relationship-role-name>
<multiplicity>Many</multiplicity>
<relationship-role-source>
<ejb-name>LineItemEJB</ejb-name>
</relationship-role-source>
</ejb-relationship-role>
</ejb-relation>部署描述
如果将容器管理字段映射到数据库字段,必须给部署者提供映射信息。具有容器管理持久性 Bean 的每个模块都必须具有以下用于部署过程的文件。
- ejb-jar.xml—包含 Bean 的事务属性、要予以容器管理的 Bean 的字段等信息。
- sun-ejb-jar.xml—组装 Enterprise Bean 的标准文件。有关信息,请参阅“sun-ejb-jar.xml 文件中的元素”以及“示例 EJB XML 文件”。
- sun-cmp-mappings.xml—用于映射容器管理持久性的文件。有关信息,请参阅“sun-cmp-mappings.xml 文件中的元素”以及“示例Schema定义”。
持久性管理器
在 Sun ONE 应用服务器中,容器管理持久性模型以可插拔持久性管理器 API 为基础,可插拔持久性管理器 API 提供持久性管理器在定义和支持实体 Bean 和持久性存储区之间的映射的角色。
持久性管理器是负责安装在容器中的实体 Bean 的持久性的组件。持久性管理器供应商提供的类负责管理实体 Bean 之间的关系,以及负责管理对其持久状态的访问。持久性管理器供应商还负责用于维持容器管理关系的 Java 类的实施。持久性管理器使用容器提供的数据源注册表访问数据源。
下图显示持久性在 Sun ONE 应用服务器环境中的工作方式。
也可以编写自定义持久性管理器来支持原有系统,或实施可提高容器管理持久性解决方案性能的缓存策略。
使用容器管理持久性
使用容器管理持久性实体 Bean 的实施很大程度上是一件映射和组装/部署的事情。
注意 必须把指定给容器管理器字段的 Java 类型限制在以下类型:Java 基元类型、Java 可序列化类型以及 EJB 远程接口或远程home接口的引用。
本节介绍以下主题:
过程概述
容器管理持久性过程包含三项操作:映射、部署和运行。这三项操作按照下述阶段完成:
阶段 1. 创建映射部署描述符文件
注意 Sun ONE Studio IDE 将自动创建此描述符,以便进行部署。
可以在用 Sun ONE Studio 4 IDE 开发容器管理持久性 Bean 的同时或在开发之后、准备部署时,执行此阶段。
在此阶段,可以把 CMP 字段和 CMR 字段(关系)映射到数据库。可以为每个容器管理持久性 Bean 选择一个主表,也可以随意选择多个次表。CMP 字段映射到主表或次表的列。CMR 字段映射到列列表对(正常情况下,列列表为与主键和外键对关联的列的列表)。
- 映射保存在一个符合 sun-cmp-mapping_1_0.dtd 的文件中,产生的 XML 文件与一个 EJB JAR 文件中的用户定义 Bean 类封装在一起,并且必须命名为 META-INF/sun-cmp-mappings.xml。
- 部署过程中报告错误。可以从 Sun ONE Studio 4 环境或在命令行触发错误。
- 映射信息是随数据库schema文件一起生成的。必须使用 Sun ONE Studio 4 IDE(“捕获schema”)或 capture-schema 实用程序捕获此文件“使用 capture-schema 实用程序”)。
- 如果更改数据库表schema,就在数据库管理员更新表后,先捕获已更新表的schema。然后,重新映射 CMP 字段和关系。
注意 没有执行此重新映射的自动过程。必须手动重新映射。
阶段 2. 生成和编译具体 Bean 和代理
此阶段是在把 EJB 应用程序部署到 Sun ONE 应用服务器过程中完成的。在此阶段,部署信息与阶段 1 创建的映射信息合并在一起。
生成以下文件:
- 具体 Bean 文件,该文件扩展您所编写的抽象 Bean
具体 Bean 实施 EJB 生命周期方法 ejbSetEntityContext、ejbUnsetEntityContext、ejbCreate、ejbRemove、ejbLoad、ejbStore。该具体 Bean 还包含针对每个 CMP 字段和 CMR 字段、ejbFindByPrimaryKey、其他查找程序方法以及用户定义的任何选择程序方法实施 getXXX 和 setXXX。
- 查找程序和选择程序方法的 EJB-QL,存储为属性文件
- 向您报告错误的生成日志文件,包括 EJB-QL 语法错误和使用错误
- 状态和帮助器类
阶段 3. 在 Sun ONE 应用服务器运行时运行
运行时,部署时提供的信息用于为作为 Enterprise Bean 实施的实体的请求提供服务。
映射功能
映射指将一个面向对象的模型捆绑到一个关系数据模型(通常是一个关系数据库schema)的能力。容器管理持久性能够把一组包含数据和关联行为的相关类捆绑到架构的相关元数据。然后,您可以使用数据库的此对象表现形成 Java 应用程序的基础。您也可以自定义此映射,以便根据某个应用程序的具体需要优化这些基本类。
结果产生一个单一数据模型,通过该模型,您可以访问持久性信息和常规瞬时程序数据。您只需要了解 Java 编程语言对象;您不需要知道或了解基本数据库schema。
有关容器管理持久性 DTD 和 XML 文件元素的信息,请参阅“sun-cmp-mappings.xml 文件中的元素”。
映射特性
Sun ONE 应用服务器提供的映射功能包括:
- 将容器管理持久性 Bean 映射到单个表
- 将容器管理持久性 Bean 映射到多个表
- 将容器管理持久性字段映射到列
- 将容器管理持久性字段映射到不同列类型
- 映射具有复合主键的表
- 将容器管理持久性关系映射到外键列
- 映射包含重叠主键和外键的表
映射工具
映射工具生成将实体 Bean 的容器管理字段映射到某个数据源(如某个关系数据库表中的列)的信息。此映射信息存储在一个 XML 文件中。
容器管理持久性实现的中间会合映射使用“映射工具”在现有架构和现有 Java 类之间创建一个自定义映射。
映射技术
容器管理持久性类应代表一个数据实体,例如一个员工或一个部门。要建立某个数据实体的模型,您需要将持久性字段添加到与数据存储区中的列相对应的类。
最简单的建模方式是让一个能够持久的类在数据存储区中表示单个表,该表的每个列都有一个持久性字段。例如,Employee 类具有数据存储区的 EMPLOYEE 表中找到的所有列的持久性字段,例如,lastname、firstname、department 和 salary。
注意 您可以选择将一个数据存储区列子集用作持久性字段,但是,如果某个字段为持久的,就必须映射该字段。
有关如何使用 Sun ONE Studio 4 映射 Enterprise Bean 的容器管理持久性的信息,请参阅 Sun ONE Studio 4 联机帮助的“Sun ONE 应用服务器集成模块”。
支持的映射数据类型
容器管理持久性支持一组 JDBC 1.0 SQL 数据类型,它们用于将 Java 数据字段映射到 SQL 类型。下表列出支持的 JDBC 1.0 SQL 数据类型。
支持的 JDBC 1.0 SQL 数据类型
BIGINT
DOUBLE
SMALLINT
BIT
FLOAT
TIME
BLOB
INTEGER
TIMESTAMP
CHAR
LONGVARCHAR
TINYINT
DATE
NUMERIC
VARCHAR
DECIMAL
REAL
下表包含建议的映射。
建议的数据类型映射
BLOB 支持
二进制大对象 (BLOB) 是一种用于存储和检索复杂对象字段的数据类型。BLOB 是二进制或序列化对象(例如,图片),这些对象可以转换为大字节数组,然后可以把这些数组序列化为 CMP 字段。
注意 在 Oracle 上,不可能使用 Oracle 瘦驱动程序(JDBC 类型 4)将 2000 多个数据字节插入一个列。要解决此问题,请使用 OCI 驱动程序(JDBC 类型 2)。
要在 Sun ONE 应用服务器环境中启用 BLOB 支持:
- 用一个可序列化类型声明 Bean 类中的变量。
- 通过在 sun-cmp-mappings.xml 文件中声明映射部署描述符,编辑 XML 文件。
- 在数据库中创建 BLOB。
注意 BLOB 对象的大小可能会影响性能。
示例
<cmp-field-mapping>
<field-name>syllabus</field-name>
<column-name>COURSE.SYLLABUS</column-name>
</cmp-field-mapping>示例
/******************************************************
Serializable class Syllabus : BLOB Testing
******************************************************/package collegeinfo
public class Syllabus implements java.io.Serializable
{
public String author;
public String syllabi;
}Schema for Course:
table course
------------
courseId Number
deptId Number
courseName Varchar
syllabus BLOB使用 capture-schema 实用程序
要想进行首先要获数据库的schema。使用 capture-schema 命令,把数据库元数据(schema)存储在一个文件中,以便在映射和执行时使用。您也可以使用 Sun ONE Studio(旧称 Forte for Java)IDE 捕获数据库schema;请参阅“捕获schema”。
语法
capture-schema -dburl url -username name -password password -driver ajdbcdriver [-schemaname name] [-table TableName]* [-out filename]
其中:
-dburl url:指定访问数据库的驱动程序需要的 JDBC URL。
-username name:指定用于验证对数据库进行访问的用户名。
-password password:指定访问选定数据库的密码。
-driver ajdbcdriver:指定 JDBC 驱动程序类名称。此类必须在您的 CLASSPATH 中。
-schemaname name:指定所捕获的用户schema的名称。如果未指定,就默认为从此用户可访问的所有schema捕获所有表中的元数据。
注意 强烈建议指定此参数。如果此用户可以访问不只一个schema,则可能捕获包含同一名称的不只一个表,这会导致问题。
-table TableName:指定一个表名称。可以指定多个表名称。如果不指定,就捕获数据库schema中的所有表。
-out:指定输出目标。默认为 stdout。要想能够使用 CMP 映射的输出,输出文件名必须具有 .dbschema 后缀。
对于容器管理持久性映射,-out 参数与 sun-cmp-mapping_1_0.dtd 文件中的 sun-cmp-mapping 元素的 schema 子元素关联:
<!ELEMENT sun-cmp-mapping ( schema, entity-mapping+) >
在 sun-cmp-mappings.xml 文件中,必须将此元素表示为没有 .dbschema 后缀。例如:
<schema>RosterSchema</schema>
注意 如果没有给出表日志,就在schema中捕获数据库中的所有表。
示例
capture-schema -dburl jdbc:pointbase:server://localhost:9092/sample -username public -password public -driver com.pointbase.jdbc.jdbcUniversalDriver -out RosterSchema.dbschema
映射字段和关系
本节讲述如何通过编辑 sun-cmp-mappings.xml 部署描述符映射实体 Bean 的字段和关系。这可以通过手动方式(假如熟悉编辑 XML 的话)或使用 Sun ONE 应用服务器组装和部署工具进行。
容器管理持久性 Bean 有一个名称、一个主表、一个或多个字段、零或多个关系以及零或多个次表,再加上用于一致性检查的标志。需要使用 sun-cmp-mappings.xml 文件中的元素把 CMP 字段和 CMR 字段映射到数据库。CMP 字段被映射到主数据库表或次数据库表中的列;CMR 字段被映射到列列表对。
“sun-cmp-mappings.xml 文件中的元素”中包含一个按字母顺序排列的列表,该列表列出容器管理持久性部署描述符中的映射元素。“示例定义”中包含一个示例 XML 文件。
本节包含完成以下映射任务的说明:
指定要映射的 Bean
您必须首先使用以下元素指定数据库schema和所映射的容器管理持久性 Bean:
sun-cmp-mappings
指定将在 EJB JAR 集合中映射的所有 Bean 的子元素的集合。
子元素为 sun-cmp-mapping。
示例
请参阅“示例Schema定义”。
sun-cmp-mapping
指定映射到特定架构的 Bean。
子元素为 schema, entity-mapping。
schema
指定架构文件的路径。仅需要一个。有关详细信息,请参阅“示例 EJB QL 查询”和“捕获schema”。
示例
<schema>RosterSchema</schema>
entity-mapping
指定将 Bean 映射到数据库列。
子元素为 ejb-name, table-name, cmp-field-mapping, cmr-field-mapping, secondary-table, consistency。
示例
有关示例,请参阅“entity-mapping”。
指定映射组件
下一步是使用以下元素指定作为映射组成部分的组件以及表明一致性检查如何发生。
entity-mapping
指定将 Bean 映射到数据库列。
子元素为 ejb-name、table-name、cmp-field-mapping、cmr-field-mapping、secondary-table、consistency。
示例
<entity-mapping>
<ejb-name>Player</ejb-name>
<table-name>PLAYER</table-name>
<cmp-field-mapping>
<field-name>salary</field-name>
<column-name>PLAYER.SALARY</column-name>
</cmp-field-mapping>
<cmp-field-mapping>
<field-name>playerId</field-name>
<column-name>PLAYER.PLAYER_ID</column-name>
</cmp-field-mapping>
<cmp-field-mapping>
<field-name>position</field-name>
<column-name>PLAYER.POSITION</column-name>
</cmp-field-mapping>
<field-name>name</field-name>
<column-name>PLAYER.NAME</column-name>
</cmp-field-mapping>
<cmr-field-mapping>
<cmr-field-name>teamId</cmr-field-name>
<column-pair>
<column-name>PLAYER.PLAYER_ID</column-name>
<column-name>TEAMPLAYER.PLAYER_ID</column-name>
</column-pair>
<column-pair>
<column-name>TEAMPLAYER.TEAM_ID</column-name>
<column-name>TEAM.TEAM_ID</column-name>
</column-pair>
</cmr-field-mapping>
</entity-mapping>ejb-name
指定文件中实体 Bean 的名称,容器管理持久性 Bean 与该文件相关。只需一个。
示例
<ejb-name>Player</ejb-name>
table-name
指定数据库表的名称。数据库schema文件中必须有该表。只需一个。
示例
<table-name>PLAYER</table-name>
secondary-table
指定 Bean 的次表。可选。
子元素为 table-name、column-pair。
示例
此次表示例在 StudentEjb 类中添加一个电子邮件字段。
public abstract class StudentEJB implements EntityBean {
/***************************************************
Write ur set,get methods for Entity bean variables and
business methods here
***************************************************/
//Access methods for CMP fields
public abstract Integer getStudentId();
public abstract void setStudentId(Integer studentId);
public abstract String getStudentName();
public abstract void setStudentName(String studentName);public abstract void setEmail(String Email); <-----Column from
Secondary Table应通过外键使“学员”和“电子邮件”表相关。“电子邮件”表的架构看起来可能是下面的样子:
Table Email:
------------
Student_id Number
email varcharTable Student:
--------------
StudentId Number
StudentName varchar
deptId Number
AddressId Number
AccountId Varchar添加次表时,两种表都适用于同一 Enterprise Bean。
consistency
指定保证 Bean 中数据事务一致性的容器行为。可选。如果没有一致性检查标志元素,则显示无。
下表描述一致性检查中使用的元素。
一致性标志
指定字段映射
字段映射是使用以下元素进行的:
cmp-field-mapping
cmp-field-mapping 元素将一个字段与其映射到的一个或多个列关联。这样的列可以来自一个 Bean 的主表或任何定义的次表。如果将一个字段映射到多个列,就把首先列出的列用作用于从数据库中获取值的 SOURCE。更新这些列,以便使其显示。 EJB JAR 文件中定义的每个 cmp-field 元素都有一个 cmp-field-mapping 元素。
可以把一个字段标记为只读。
子元素为 field-name、column-name、read-only 和 fetched-with。
示例
<cmp-field-mapping>
<field-name>name</field-name>
<column-name>LEAGUE.NAME</column-name>
</cmp-field-mapping>field-name
指定一个字段的 Java 标识符。此标识符匹配所映射的 cmp-field 的 field-name 子元素的值。必需一个此子元素。
示例
<field-name>name</field-name>
column-name
指定主表中某个列的名称,或者指定次表或相关中的某个列的合格名称 (TABLE.COLUMN)。需要一个或多个子元素。
注意 映射多个列时,可以使用任意 JAVA 类型。
示例
<column-name>PLAYER.NAME</column-name>
示例
将此与多个地方有同样信息的非标准化表一起使用,如果此子元素已更新,则需要使信息保持同步。
public abstract class StudentEJB implements EntityBean {
.
.
.
public abstract String getInstallments();可以把“学员”(student) 表中的三个列映射到“学员”Enterprise Bean 中的单个安装列中。
Table student:
.
.
.
installment1 Number
installment2 Number
installment3 Number将同一值写到数据库的所有列中。
read-only
read-only 标志表示字段为只读。
示例
<read-only>name</read-only>
fetched-with
指定字段和关系的 fetch 组配置。一个字段可以加入某个分层或独立 fetch 组。可选。
fetched-with 元素的默认值会因其上下文的不同而不同。
- 如果没有 cmp-field-mapping 的 fetched-with 子元素,默认值就假定为:
<fetched-with><level>0</level></fetched-with>
- 如果没有 cmr-field-mapping 的 fetched-with 子元素,默认值就假定为:
<fetched-with><none/></fetched-with>
子元素为 level、named-group 或无子元素。
level
指定分层 fetch 组的名称。值必须为整数。同时获取属于等于(或小于)值的一个分层 fetch 组。level 的值必须大于零。仅允许有一个此子元素。
named-group
指定一个独立 fetch 组的名称。同时获取属于一个命名组的所有字段和关系。仅允许有一个此子元素。
none
一致性水平标志,表示此字段或关系由其本身获取。
指定关系
以下元素用于为容器管理关系指定映射:
cmr-field-mapping
容器管理关系字段具有一个名称以及一个或多个定义关系的列对。 每个 cmr-field 有一个 cmr-field-mapping 元素。关系也可以参与 fetch 组。
子元素为 cmr-field-name、column-pair、fetched-with。
示例
<cmr-field-mapping>
<cmr-field-name>teamId</cmr-field-name>
<column-pair>
<column-name>PLAYER.PLAYER_ID</column-name>
<column-name>TEAMPLAYER.PLAYER_ID</column-name>
</column-pair>
<column-pair>
<column-name>TEAM.TEAM_ID</column-name>
<column-name>TEAMPLAYER.TEAM_ID</column-name>
</column-pair>
<fetched-with>
<none/>
</fetched-with>
</cmr-field-mapping>cmr-field-name
指定字段的 Java 标识符。这必须匹配所映射的 cmr-field 的 cmr-field-name 子元素的值。必需一个。
示例
<cmr-field-name>team</cmr-field-name>
column-pair
指定两个数据库表中的相关列对。需要一个或多个。
列名称在 column-name 元素中指定。
示例
<column-pair>
<column-name>PLAYER.PLAYER_ID</column-name>
<column-name>TEAMPLAYER.PLAYER_ID</column-name>
</column-pair>column-name
指定主表中某个列的名称,或者指定次表或相关表中某个列的合格名称 (TABLE.COLUMN)。需要两个作为 column-pair 的子元素。
示例
<column-name>PLAYER.NAME</column-name>
fetched-with
指定字段和关系的 fetch 组配置。字段可以参与分层或独立 fetch 组。可选。
根据具体上下文, fetched-with 元素具有不同的默认值。
- 如果没有 cmp-field-mapping 的 fetched-with 子元素,采用的默认值为:
<fetched-with><level>0</level></fetched-with>
- 如果没有 cmr-field-mapping 的 fetched-with 子元素,采用的默认值为:
<fetched-with><none/></fetched-with>
子元素为 level、named-group 或 none。
配置资源管理器
容器管理持久性实现使用的资源管理器是 PersistenceManagerFactory,该资源管理器是使用 Sun ONE 应用服务器 DTD 文件 sun-server_7_0-0.dtd 配置的。
有关创建新持久性管理器的信息,请参阅 Sun ONE 应用服务器管理员指南。
要部署一个包含容器管理持久性 Bean 的 EJB 模块,需要将以下信息添加到 sun-ejb-jar.xml 部署描述符。
- 指定要用于部署的持久性管理器:
<pm-descriptors>
<pm-descriptor>
<pm-identifier>SunONE</pm-identifier>
<pm-version>1.0</pm-version>
<pm-class-generator>com.iplanet.ias.persistence.internal.ejb.ejbc.J DOCodeGenerator
</pm-class-generator>
<pm-mapping-factory>com.iplanet.ias.cmp.
NullFactory</pm-mapping-factory>
</pm-descriptor
<pm-inuse>
<pm-identifier>SunONE</pm-identifier>
<pm-version>1.0</pm-version>
</pm-inuse>
</pm-descriptors>- 指定持久性管理器的资源的 JNDI 名称(server.xml 文件中的 persistence-manager-factory-resource 实体下列出)以及 cmp-resource 的 JNDI 名称。运行时,将使用此名称管理持久资源。
例如,如果 server.xml 文件中有以下输入内容:
<persistence-manager-factory-resource
factory-class="com.sun.jdo.spi.persistence.support.
sqlstore.impl.PersistenceMan
gerFactoryImpl"
enabled="true"
jndi-name="jdo/pmf"
jdbc-resource-jndi-name="jdo/pmfPM"
</persistence-manager-factory-resource>请将 CMP 资源设置为:
<cmp-resource>
<jndi-name>jdo/pmf</jndi-name
</cmp-resource>
注意 Sun ONE Studio IDE 将自动把 pm-descriptors 创建为此标识符的组成部分,以便于部署。关于如何设置容器管理持久性资源的信息,请参阅 Sun ONE Studio 4 联机帮助的 Sun ONE 应用服务器集成模块。
使用 EJB QL
Enterprise JavaBeans Specification 2.0 指定一种新的查询语言 (EJB QL),这种查询语言可用来为 CMP Bean 的查找程序和选择方法定义可移植查询。这些查询使用一种 SQL 式语法根据 CMP Bean 的抽象Schema类型和关系选择实体对象或字段值。
查找程序方法是在 Bean 的主和/或本地home接口以及同一 Bean 的返回实例中定义的。抽象 Bean 类仅在选择方法中定义,并可用于从同一架构中选择任何本地或远程类型的实体对象以及 Bean 的字段值。
有关详细信息,请参阅 Enterprise JavaBeans Specification 2.0 中的第 11 章“EJB QL:用于容器管理持久性查询方法的 EJB 查询语言”。
有些 EJB QL 示例查询包含在“示例 EJB QL 查询”之中。
为 1.1 查找程序配置查询
Enterprise JavaBeans Specification 1.1 规范不指定查找程序方法说明的格式。Sun ONE 应用服务器使用 Java 数据对象查询语言 (JDOQL) 查询实施查找程序和选择程序方法。如果是 EJB 2.0,容器自动将 EJB QL 查询映射到 JDOQL。如果是 EJB 1.1,此映射部分地由开发者执行。您可以指定基本 JDOQL 查询的以下元素:
- 筛选表达式 - 一种 Java 式表达式,指定查询返回的每个对象必须满足的某种条件。与 EJB QL 中的 WHERE 子句相对应。
- 查询阐述声明 - 指定一个或多个查询输入参数的名称和类型。遵循 Java 语言中正式参数的语法。
- 查询变量声明 - 指定一个或多个查询变量的名称和类型。遵循 Java 语言中本地参数的语法。可以在筛选器中使用查询变量实施联接。
Sun ONE 应用服务器特有的部署描述符 (sun-ejb-jar.xml) 提供以下元素存储 EJB 1.1 查找程序方法设置:
query-filter
query-params
query-variables将 EJB 1.1 实体 Bean 的有持久能力的类用作候选类,Sun ONE 应用服务器构造 JDOQL 查询。Sun ONE 应用服务器添加筛选器、参数声明和开发者指定到 JDOQL 查询的变量声明。Sun ONE 应用服务器执行查询,并将查找程序方法的参数传递到 execute 调用。将 JDOQL 查询结果集的对象转换为要由 EJB 1.1 ejbFind 方法返回的主键实例。
JDO 规范(请参阅 JSR 12)提供 JDOQL 的全面说明。以下信息概述用于定义 EJB 1.1 查找程序的元素。
查询筛选表达式
筛选表达式是一个字符串,该字符串包含针对候选类的每个实例估计的布尔表达式。如果不指定筛选器,筛选器就默认为 True(真)。构造有效表达式的规则遵循 Java 语言,并具有以下不同之处:
- 包装类的基元和实例之间的等式和排序比较有效。
- “日期”字段和“日期”参数的等式和排序比较有效。
- 字符串字段和字符串参数的等式和排序比较有效。
- 空白区域(非打印字符空间、制表符、回车以及换行)为分隔符,并被以其他方式忽略。
- 不支持以下分配运算符:
- 不支持包括对象构造在内的方法,但以下例外。
- 对待浏览空值字段(该字段丢弃 NullPointerException)的方式就像子表达式返回 False(假)一样。
注意 浮点值之间的比较本质上是不精确的。因此,使用包含浮点值的等式比较(== 和 !=)时,要谨慎。表达式中的标识符被视为处于候选类的名称空间,增加了声明参数和变量。在 Java 语言中,这是一个预定字,指正在确定其值的当前实例。
支持以下表达式:
- 运算符,适用于用 Java 语言定义的所有类型:
- 明确表示运算符首选项的括号
- Cast 运算符
- 用于比较和算术运算的数字操作数。升级规则遵循 BigDecimal、BigInteger 和数字包装类扩展的 Java 规则(请参阅 Java 语言规范的数字升级)。
查询参数
参数声明是一个字符串,该字符串包含一个或多个由逗点隔开的参数类型声明。这遵循方法签名的 Java 语法。
查询变量
类型声明遵循用于本地变量声明的 Java 语法。
示例 1
以下查询返回称为 Michael 的所有演员 (player)。它定义将名称字段与一个字符串 literal 比较的筛选器:
"name == \"Michael\""
sun-ejb-jar.xml 文件的 finder 元素看起来就像以下样子:
<finder>
<method-name>findPlayerByName</method-name>
<query-filter>name == "Michael"</query-filter>
</finder>示例 2
此查询返回指定价格范围的所有产品。它定义两个查询参数,它们是价格的低限和高限:double low, double high。筛选器将查询参数与价格字段进行比较:
"low < price && price < high"
sun-ejb-jar.xml 文件的 finder 元素看起来就像以下样子:
<finder>
<method-name>findInRange</method-name>
<query-params>double low, double high</query-params>
<query-filter>low < price && price <
high</query-filter
</finder>示例 3
此查询返回拥有比指定名称的演员所拥有的较高薪金的所有演员。它定义 java.lang.String name 名称的查询参数。另外,它还定义要与其比较的演员的变量。它具有与 Bean 对应的能够持久的类的类型:
mypackage.PlayerEJB_170160966_JDOState p
该筛选器将此关键字表示的当前演员的薪金与具有指定姓名的演员的薪金进行比较:
(this.salary > p.salary) && (p.name == name)
sun-ejb-jar.xml 文件的 finder 元素看起来就像以下样子:
<finder>
<method-name>findByHigherSalary</method-name>
<query-params>java.lang.String name</query-params>
<query-filter>
(this.salary > p.salary) &&
(p.name ==name)
</query-filter>
<query-variables></query-variables
</finder>第三方可插拔持久性管理器 API
EJB 容器中的容器管理持久性可支持持久性供应商,他们使用 Sun ONE 应用服务器可插拔持久性管理器 API 将其运行时集成到 Sun ONE 应用服务器。API 描述部署时、生成代码时以及运行时的集成要求。编译 EJB 时,API 支持执行具体 Bean 实现的标注。
Sun ONE 应用服务器使容器管理持久性实现能够使用其启动框架来加载类以及注册持久性管理器。可插拔持久性管理器 AP还支持与事务处理和动态部署相关的集成要求。
一般说来,目的是使完全支持 Enterprise JavaBeans Specification 2.0 的任何第三方容器管理持久性解决方案可以与 Sun ONE 应用服务器一起工作。
要使用第三方工具:
第三方持久性工具必须在运行时使用 Java 数据库连接 (JDBC) 资源或 Java 连接器 API (JCA) 资源,访问关系数据源。这使可插拔持久性管理器可以自动使用“连接合用”、事务处理以及容器的安全管理特性。第三方供应商将能够插入其具体类生成器机器映射工厂,以便生成有效的针对供应商的映射对象模型。
配置要求指定必须为一个 Bean 定义的许多属性,其中包括:
限制和优化
本节讨论针对实体 Bean 实施容器管理持久性时应了解的任何限制和性能优化。
EAR 文件中的唯一数据库schema名称
在一个 EAR 文件中存储多个 JAR 文件(例如 jar1 和 jar2)的情形下,jar1 和 jar2 的任何相应的数据库schema文件都必须具有完全合格的名称。
换句话说,在一个给定 EAR 文件中,数据库schema文件名称必须是唯一的。
容器管理持久性协议的局限性
- 数据别名问题 - 如果多个实体 Bean 的容器管理字段映射到基本数据库中的同一数据项,而且在同一事务处理中调用多个实体 Bean,这些实体 Bean 就可以看到一个不一致的数据项视图。
- 过早加载状态 - 在调用抽象 Bean 的 ejbLoad 方法之前,容器将整个实体对象状态加载到容器管理字段中。如果实体对象拥有大量的状态,而大多数商业逻辑调用只访问部分状态,这种过早加载状态的方法就显得不那么优化了。如果这是一个问题,请将<fetched-with> 元素用于那些不频繁使用的字段的 。
关于远程接口的限制
下列限制适用于使用容器管理持久性的实体 Bean 的远程接口:
- 不要公开容器管理关系字段的 get 和 set 方法,和用于容器管理关系的持久性“集合”类。
- 不要通过 Bean 的远程接口和远程home接口来公开本地接口类型或本地home接口类型。
- 不要通过 Bean 的远程接口公开用于关系的容器管理集合类。
可以用远程接口或远程home接口公开相关值类,而且可以把这些相关值类包含在客户端 EJB JAR 文件中。
sun-cmp-mappings.xml 文件中的元素
“组装和部署 Enterprise Bean”介绍关于组装要部署 Enterprise Bean 的一般信息和准则。其他部署信息和说明包含在 Sun ONE 应用服务器开发者指南之中。
“持久性元素”提供 sun-ejb-jar.xml 文件中与持久性相关的元素的信息。
“示例Schema定义”中包含一个示例 XML 文件。
本节讲述 sun-cmp-mappings.xml 文件中的元素:
- check-all-at-commit
- check-modified-at-commit
- cmr-field-mapping
- cmr-field-name
- column-name
- column-pair
- consistency
- ejb-name
- entity-mapping
- fetched-with
- field-name
- level
- lock-when-loaded
- lock-when-modified
- named-group
- none
- read-only
- schema
- sun-cmp-mapping
- sun-cmp-mappings
- table-name
check-all-at-commit
没有针对 Sun ONE Application Server 7 实施此标志。
子元素
无
check-modified-at-commit
持久性级别标志,表示将在 commit 时检查已修改 Bean 实例。
子元素
无
cmp-field-mapping
cmp-field-mapping 元素将一个字段与其映射到的一个或多个列关联。这样的列可以来自一个 Bean 的主表或任何定义的次表。如果将一个字段映射到多个列,就把首先列出的列用作用于从数据库中获取值的 SOURCE。更新这些列,以便使其显示。EJB JAR 文件中定义的每个 cmp-field 元素都有一个 cmp-field-mapping 元素。
可以把一个字段标记为只读。
如果未指定 fetched-with 元素,字段就可以参加 fetch 组:
<fetched-with><level>0</level></fetched-with>
子元素
下表描述 cmp-field-mapping 元素的子元素。
cmp-field-mapping 子元素
子元素
必需
说明
仅一个
指定一个字段的 Java 标识符。此标识符必须匹配所映射 cmp-field 的 field-name 子元素的值。必需一个此子元素。
一个或多个
指定主表中某个列的名称,或一个次表或相关表的某个列的表合格名称 (TABLE.COLUMN)。必需一个此子元素。
零或一个
表示某个字段为只读的标志。可选。.
零或一个
指定字段和关系的 fetch 组配置。可选。.
cmr-field-mapping
一个容器管理关系字段具有一个名称以及一个或多个定义该关系的列对。每个 cmr-field 有一个 cmr-field-mapping 元素。一个关系也可以参加一个 fetch 组。
如果不存在 fetched-with 元素,就假定有以下值:<fetched-with><none/></fetched-with>。
子元素
下表描述 cmr-field-mapping 元素的子元素。
cmr-field-mapping 子元素
子元素
必需
说明
仅一个
指定一个字段的 Java 标识符。必须匹配所映射的 cmr-field 的 cmr-field-name 子元素的值。
一个或多个
某个数据库中的列对的名称。
零或一个
指定字段和关系的 fetch 组配置。可选。
cmr-field-name
指定一个字段的 Java 标识符。必须匹配所映射的 cmr-field 的 cmr-field-name 子元素的值。
子元素
无
column-name
指定主表中某个列的名称,或一个次表或相关表的某个列的表合格名称 (TABLE.COLUMN)。必需一个此子元素。必需一个此子元素。
子元素
无
column-pair
两个数据库表中相关列对的名称。必需一个此子元素。
子元素
下表描述 column-pair 元素的子元素。
column-pair 子元素
子元素
必需
说明
两个
指定主表中某个列的名称,或一个次表或相关表的某个列的表合格名称 (TABLE.COLUMN)。必需一个此子元素。必需一个此子元素。
consistency
指定保证 Bean 中数据的事务处理一致性的容器行为。可选。如果不存在一致性检查标志元素,则不假定任何值。
子元素
下表描述用于一致性检查的元素。
一致性标志
标志元素
说明
检查 commit 时的已修改实例。
不对 Sun ONE Application Server 7 实施此标志。
加载数据时获取的一个单独锁定。
不对 Sun ONE Application Server 7 实施此标志。
不发生任何一致性检查。
ejb-name
指定容器管理持久性与之相关的 ejb-jar.xml 文件中的实体 Bean 的名称。必需一个此子元素。
子元素
无
entity-mapping
指定将一个 Bean 映射到数据库列。
子元素
下表描述 entity-mapping 元素的子元素。
entity-mapping 子元素
fetched-with
指定字段和关系的 fetch 组。可选。
一个字段可以参加一个分层或独立 fetch 组。如果不存在 fetched-with 元素,就假定以下值:<fetched-with><none/></fetched-with>。
子元素
下表描述 fetched-with 元素的子元素。
fetched-with 子元素
子元素
必需
说明
必须而且只能有一个这样的元素
指定一个分层 fetch 组的名称。值必须的一个整数。同时获取属于一个具有等于(小于)值的分层 fetch 组的字段和关系。level 的值必须大于零。
指定一个独立 fetch 组的名称。同时获取作为一个命名组的组成部分的所有字段和关系。
一个一致性级别标志,表示此字段或关系自行获取。
field-name
指定一个字段的 Java 标识符。此标识符必须匹配所映射的cmp-field 的 field-name 子元素的值。 必需一个此子元素。
子元素
无
level
指定一个分层 fetch 组。此元素的值必须是一个整数。同时获取属于一个具有等于(小于)值的分层 fetch 组的字段和关系。level 的值必须大于零。
子元素
无
lock-when-loaded
一个一致性级别标志,表示加载数据时将实施锁定。
子元素
无
lock-when-modified
不对 Sun ONE Application Server 7 实施此标志。
子元素
无
named-group
指定一个独立 fetch 组的名称。同时获取作为一个命名组的组成部分的所有字段和关系。允许有一个元素。
子元素
无
无
一个一致性级别标志,表示获取此字段或关系,不包含任何其他字段或关系,或者指定 fetched-with 语义。
子元素
无
read-only
表示一个字段为只读字段的标志。
子元素
无
schema
指定架构文件的路径。 仅需要一个。有关详细信息,请参阅“捕获schema”。
子元素
无
secondary-table
指定一个 Bean 的次表。
子元素
下表描述 secondary-table 元素的子元素。
secondary table 子元素
子元素
必需
说明
仅一个
指定一个数据库表的名称。该表必须存在于数据库schema文件中。
一个或多个
两个数据库表中相关列对的名称。
sun-cmp-mapping
指定映射到某个架构的 Bean。
注意 一个 Bean 不能与映射到一个不同架构的 Bean 相关,即使是在同一 EJB JAR 文件中部署这些 Bean。
子元素
下表描述 sun-cmp-mapping 元素的子元素。
sun-cmp-mapping 子元素
子元素
必需
说明
仅一个
指定架构文件的路径。
一个或多个
指定将 Bean 映射到数据库列。
sun-cmp-mappings
指定将在一个 EJB JAR 集合中映射的所有 Bean 的子元素的集合。
子元素
下表描述 sun-cmp-mappings 元素的子元素。
sun-cmp-mappings 子元素
子元素
必需
说明
一个或多个
指定映射到某个架构的 Bean。
table-name
指定某个数据库表的名称。数据库schema文件中必需存在该表。必需有一个此子元素,
子元素
无
示例
本节包含以下示例:
示例Schema定义
CREATE TABLE Player
(
player_Id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) ,
position VARCHAR(255) ,
salary DOUBLE PRECISION NOT NULL ,
picture BLOB,
);CREATE TABLE League
(
league_Id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) ,
sport VARCHAR(255) ,
);CREATE TABLE Team
(
team_Id VARCHAR(255) PRIMARY KEY,
city VARCHAR(255) ,
name VARCHAR(255) ,
league_Id VARCHAR(255) ,
FOREIGN KEY (league_Id) REFERENCES League (league_Id) ,
);CREATE TABLE TeamPlayer
(
player_Id VARCHAR(255) ,
team_Id VARCHAR(255),
CONSTRAINT pk_TeamPlayer PRIMARY KEY (player_Id , team_Id) ,
FOREIGN KEY (team_Id) REFERENCES Team (team_Id),
FOREIGN KEY (player_Id) REFERENCES Player (player_Id) ,
);示例 CMP 映射 XML 文件
有关这些元素的信息,请参阅“sun-cmp-mappings.xml 文件中的元素”。
以下示例映射文件在可部署的 EJB JAR 文件中具有名称 META-INF/sun-cmp-mappings.xml:
<?xml version="1.0" encoding="UTF-8"?>
<sun-cmp-mappings>
<sun-cmp-mapping>
<schema>RosterSchema</schema>
<entity-mapping>
<ejb-name>League</ejb-name>
<table-name>LEAGUE</table-name>
<cmp-field-mapping>
<field-name>name</field-name>
<column-name>LEAGUE.NAME</column-name>
</cmp-field-mapping>
<cmp-field-mapping>
<field-name>leagueId</field-name>
<column-name>LEAGUE.LEAGUE_ID</column-name>
</cmp-field-mapping>
<cmp-field-mapping>
<field-name>sport</field-name>
<column-name>LEAGUE.SPORT</column-name>
</cmp-field-mapping>
<cmr-field-mapping>
<cmr-field-name>team</cmr-field-name>
<column-pair>
<column-name>LEAGUE.LEAGUE_ID</column-name>
<column-name>TEAM.LEAGUE_ID</column-name>
</column-pair>
</cmr-field-mapping>
</entity-mapping>
<entity-mapping>
<ejb-name>Team</ejb-name>
<table-name>TEAM</table-name>
<cmp-field-mapping>
<field-name>name</field-name>
<column-name>TEAM.NAME</column-name>
</cmp-field-mapping>
<cmp-field-mapping>
<field-name>city</field-name>
<column-name>TEAM.CITY</column-name>
</cmp-field-mapping>
<cmp-field-mapping>
<field-name>teamId</field-name>
<column-name>TEAM.TEAM_ID</column-name>
</cmp-field-mapping>
<cmr-field-mapping>
<cmr-field-name>playerId</cmr-field-name>
<column-pair>
<column-name>TEAM.TEAM_ID</column-name>
<column-name>TEAMPLAYER.TEAM_ID</column-name>
</column-pair>
<column-pair>
<column-name>TEAMPLAYER.PLAYER_ID</column-name>
<column-name>PLAYER.PLAYER_ID</column-name>
</column-pair>
<fetched-with>
<none/>
</fetched-with>
</cmr-field-mapping>
<cmr-field-mapping>
<cmr-field-name>leagueId</cmr-field-name>
<column-pair>
<column-name>TEAM.LEAGUE_ID</column-name>
<column-name>LEAGUE.LEAGUE_ID</column-name>
</column-pair>
<fetched-with>
<none/>
</fetched-with>
</cmr-field-mapping>
</entity-mapping>
<entity-mapping>
<ejb-name>Player</ejb-name>
<table-name>PLAYER</table-name>
<cmp-field-mapping>
<field-name>salary</field-name>
<column-name>PLAYER.SALARY</column-name>
</cmp-field-mapping>
<cmp-field-mapping>
<field-name>playerId</field-name>
<column-name>PLAYER.PLAYER_ID</column-name>
</cmp-field-mapping>
<cmp-field-mapping>
<field-name>position</field-name>
<column-name>PLAYER.POSITION</column-name>
</cmp-field-mapping>
<cmp-field-mapping>
<field-name>name</field-name>
<column-name>PLAYER.NAME</column-name>
</cmp-field-mapping>
<cmr-field-mapping>
<cmr-field-name>teamId</cmr-field-name>
<column-pair>
<column-name>PLAYER.PLAYER_ID</column-name>
<column-name>TEAMPLAYER.PLAYER_ID</column-name>
</column-pair>
<column-pair>
<column-name>TEAMPLAYER.TEAM_ID</column-name>
<column-name>TEAM.TEAM_ID</column-name>
</column-pair>
</cmr-field-mapping>
</entity-mapping>
</sun-cmp-mapping>
</sun-cmp-mappings>示例 EJB QL 查询
<query>
<description></description>
<query-method>
<method-name>findAll</method-name>
<method-params />
</query-method>
<ejb-ql>select object(l) from League l</ejb-ql>
</query><query>
<description></description>
<query-method>
<method-name>findByName</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>select object(l) from League l where l.name = ?1</ejb-ql>
</query><query>
<description></description>
<query-method>
<method-name>findByPosition</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>select distinct object(p) from Player p where p.position = ?1</ejb-ql>
</query><query>
<description>Selector returning SET</description>
<query-method>
<method-name>ejbSelectTeamsCity</method-name>
<method-params>
<method-param>team.LocalLeague</method-param>
</method-params>
</query-method>
<ejb-ql>select distinct t.city from Team t where t.league = ?1</ejb-ql>
</query><query>
<description>Selector returning single object LocalInterface</description>
<query-method>
<method-name>ejbSelectTeamByCity</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<result-type-mapping>Local</result-type-mapping>
<ejb-ql>select distinct Object(t) from League l, in(l.teams) as t where t.city = ?1</ejb-ql>
</query><query>
<description>Selector returning single object String</description>
<query-method>
<method-name>ejbSelectTeamsNameByCity</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>select distinct t.name from League l, in(l.teams) as t where t.city = ?1</ejb-ql>
</query><query>
<description>Selector returning Set using multiple collection declarations</description>
<query-method>
<method-name>ejbSelectPlayersByLeague</method-name>
<method-params>
<method-param>team.LocalLeague</method-param>
</method-params>
</query-method>
<result-type-mapping>Local</result-type-mapping>
<ejb-ql>select Object(p) from League l, in(l.teams) as t, in(t.players) p where l = ?1</ejb-ql>
</query><query>
<description>Selector single object int</description>
<query-method>
<method-name>ejbSelectSalaryOfPlayerInTeam</method-name>
<method-params>
<method-param>team.LocalTeam</method-param>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>select p.salary from Team t, in(t.players) as p where t = ?1 and p.name = ?2</ejb-ql>
</query><query>
<description>Finder using the IN Expression</description>
<query-method>
<method-name>findByPositionsGoalkeeperOrDefender</method-name>
<method-params/>
</query-method>
<ejb-ql>select object(p) from Player p where p.position IN ('goalkeeper', 'defender')</ejb-ql>
</query><query>
<description>Finder using the LIKE Expression</description>
<query-method>
<method-name>findByNameEndingWithON</method-name>
<method-params/>
</query-method>
<ejb-ql>select object(p) from Player p where p.name LIKE '%on'</ejb-ql>
</query><query>
<description>Finder using the IS NULL Expression</description>
<query-method>
<method-name>findByNullName</method-name>
<method-params/>
</query-method>
<ejb-ql>select object(p) from Player p where p.name IS NULL</ejb-ql>
</query><query>
<description>Finder using the MEMBER OF Expression</description>
<query-method>
<method-name>findByTeam</method-name>
<method-params>
<method-param>team.LocalTeam</method-param>
</method-params>
</query-method>
<ejb-ql>select object(p) from Player p where ?1 MEMBER p.teams</ejb-ql>
</query><query>
<description>Finder using the ABS function</description>
<query-method>
<method-name>findBySalarayWithArithmeticFunctionABS</method-name>
<method-params>
<method-param>double</method-param>
</method-params>
</query-method>
<ejb-ql>select object(p) from Player p where p.salary = ABS(?1)</ejb-ql>
</query><query>
<description>Finder using the SQRT function</description>
<query-method>
<method-name>findBySalarayWithArithmeticFunctionSQRT</method-name>
<method-params>
<method-param>double</method-param>
</method-params>
</query-method>
<ejb-ql>select object(p) from Player p where p.salary = SQRT(?1)</ejb-ql>
</query>
| | |