具体实施方式
下面的详细描述是参照附图做出的。优选实施例说明了本发明,但不限于由权利要求所限定的范围。本领域的技术人员可以知道对下面描述的各种等价改变。
图1示出由Sun发起的J2EE和EJB标准,它们可以用于本发明的一个实施例。参见Bodoff等人的The J2EE Tutorial,p.10 Addison Wesley(2002)。Sun将图1中的模块解释如下。J2EE服务器120是J2EE产品的运行时部分。J2EE服务器提供EJB容器125和Web容器121,并管理对底层数据库层130的访问。Enterprise JavaBeans(EJB)容器125管理对J2EE应用的企业豆(enterprise beans)的执行。企业豆126、127及其容器125在J2EE服务器120上运行。Web容器121管理对用于J2EE应用的JSP页123和servlet 122组件的执行。Web组件122、123及其容器121在J2EE服务器120上运行。应用客户机容器113管理应用客户机112组件的执行。应用客户机112及其容器113在客户机110上运行。Applet容器管理applet的执行。该容器包括Web浏览器111和一个或多个在客户机110上运行的Java插件程序。
更概括地说,图1示出基于标准的服务器端的组件模型和远程方法调用协议。Microsoft的.NET框架和CORBA包括类似的组件。Monson-Haefel,EnterpriseJavaBeans,pp.5-18。本发明的方面与标准兼容,其中这些方面以这里标明或递交本申请时的当前版本或随后的版本符合该标准的任何版本或衍生物。实质兼容是很有用的,无需全部兼容。已经认识到与标准完全兼容有时需要实现被认为是不需要的标准的特征,这代价太大或变化不定。此外,还认识到有些实施会包括可能被引入来增强产品并且随着标准发展和用户坚持法律支持可能而成为非标准的特征。标准意味着覆盖诸如EJB等由委员会控制的规范以及诸如.NET框架等由供应商控制的规范。
图2示出如何采用提供中间层的J2EE服务器上的EJB来实施公用对象框架。图2的很多组件与图1的组件匹配,并根据图1来作标示。在图2中,描述了web容器和一个企业豆的内容。在web容器121中,应用包括公用对象框架(COF)240A、角色应用241、web服务引擎242和协作过程管理器243。COF为持续对象提供支持并提供对它的访问,以减少角色应用241的开发者处理持续性、事务管理和相关任务的需要。通过采用本申请和通过引用而合并的申请中描述的方法,COF可选地可以支持分段、变化历史、国际化和水平分割。Web服务引擎242和协作过程管理器是由Commerce One用于提供web服务的组件;在web容器中的这些应用的细节对本发明并不重要。但是,将协作过程管理器243连接到COF240A的实心箭头以及将CPM243连接到COF240B和EJB127的虚线示出用EJB容器124提供的服务和数据支持来代替web容器121中的COF240A代码所提供的服务的选项。将Web容器121中的COF代码和企业豆126类似地标注为240A、240B意味着表示COF代码可以打包用于EJB处理,并在改动很少或不重写COF代码的情况下具有EJB兼容的接口。如图所示,COF可以在web容器或EJB容器中获得。应用可以访问两个容器中的COF组件。应用可以与两套COF组件同时或并发地进行主动会话。虽然图2示出在EJB环境的语境中的实施,本领域的技术人员可以认识到相同的方法可以用于其它基于标准的服务器端组件模型和远程方法调用协议,如DCOM。
所谓的公用对象框架提供用于管理业务对象的整个软件生命周期的基本实现和工具,这在合并的申请中有更为详细的描述。这包括设计、UML模型、完整的代码和数据库产生,这些都包括透明的国际化、分段、变化历史和定制属性。为正在进行的对依赖数据库的代码、数据和模式的维护提供工具。公用对象框架组件的种类包括实用程序(utilities)库、业务对象框架和系统管理工具。实用程序库组件包括公共代码级的实用程序,如Exceptions(国际化的)(例外)、Logging(日志)、Cryptography(密码)和Configuration(配置)访问。实用程序库组件还包括国际化功能,如资源管理器、日期、数值和文本。业务对象框架用于设计业务对象、产生用于持续、国际化、数据分段、版本历史、动态定制属性和完全创建/读取/更新/删除(CRUD)功能的代码。该框架还包括对扩展任何业务对象、跨多个服务器的高速缓存同步的支持以及调度程序。系统管理工具建立在业务对象框架的基础上,包括用于创建数据库、加载数据、更新数据库模式和更新数据的释放更改的数据管理工具。还有用于国际化和本地化工具包的提取程序和安装程序。
EJB兼容的COF或标准兼容的COF可以由各种软件组件实现以及与它们交互地实现。对象模型的设计以及代码或元数据(机器可读数据)的产生可以用Rational Rose 2001a或更高版本来实现。在此和下面,版本“2001a”也只用于参考,并不意味着对可用于实施本发明方面的软件的版本进行限制。在使用Rational Rose时,安装一个附加项来提供图4-5示出的和在下面解释的功能。可以采用TopLink3.6.1、SQL Server 2000、Oracle 8.1.7或DB2、以及诸如I-netOPTA4.15、Seropto或IDS JDBC Lite3.5.4的适当JDBC驱动程序来映射、创建和访问数据库。可以采用诸如WebSphere和WebLogic7.0的EJB容器。
可用多种有用方式来组合EJB兼容的COF的新的和增强的模块。这些模块生成远程和本地EJB接口,从而任何COF对象都可以象EJB那样被访问和使用。它们采用TOPLink4.0作为OR映射工具,提供对作为用于找到对象的查询语言的EJB-QL的访问。这些模块管理数据库服务器会话,包括支持对多个数据库的同时访问和对数据的水平分割。数据库之间的关系无法得到支持。这些模块对对任何对象进行访问的应用提供客户机会话。它们为丢失的数据库连接提供可配置的重试机制。它们支持与基于EJB JTA的事务和在数据库服务器间唯一的唯一连接对象标识符进行集成,以在在数据库间迁移时保留对象标识符并实现水平分割。对象改变事件消息作为对象创建、更新和删除的可配置事件产生。向实现的对象提供复查,以用于后对象创建、前对象更新、后对象刷新和前对象删除。为Rational Rose提供了设计和代码生成工具。数据库创建工具基于可视模型化的设计来生成数据库或DDL脚本。工具为所生成的EJB产生应用服务器配置描述器。支持WebLogic6.1sp2和WebSphere 5.0(需要EJB2.0spec的支持)。
图3示出可视模型化的简单购物车应用的对象和关系。该图中的模型是利用用于类图的统一建模语言(UML)符号创建的。在该例中,CmsCart对象301用于提供多个外露的方法。采用CmsCart而不是CmoCart对象意味着该对象在会话期间存在,并且对后一个会话不是持续的,这与顾客和订单相反,后者是持续的。购物车301可以通过订单311与CmoOrder对象303关联。在该例中,一个订单对象涉及一个购物车。CmoOrder对象303在完成后应当通过CmoCustomer对象302与顾客313关联。沿着该关系的反方向,持续顾客302可以将312与不止一个订单303关联。订单303包含一个或多个CmoProductLineItem对象305。关系项314将订单303与其线项目305相连。线项目305填充了通过产品315关系连接到该线项目的产品304。
在UML中,诸如购物车的对象可以被模型化为一个类。在默认的情况下,在本发明实施例中的所有顶级(即没有父类)的持续对象都从称为CmoBase的基本对象继承而来,如下面将在图5的上下文中解释的。或者,临时对象可以从称为CmsBase的对象继承而来。该基本对象可以在CAT(或单元)文件中提供,该文件可以加载到对象建模程序中,并被其它类引用。该基本类的目的是对所有通用公共接口和实现的对象提供基本功能。
用对象建模程序建立UML格式的类的模型可以包括以下步骤。首先,创建包(package)层次,以指定该类应在的和在那里产生的目录结构。然后可以指定类名、类文档和类属性。采用如图4示出的和下面解释的工具来支持的类属性包括:持续、临时、摘要、生成代码、数据库表名、可分段、最大版本号、表层(Table-Level)数据库约束(例如复合的唯一约束)、在GUI中显示、显示名、显示描述、生成和生成EJB。
下面可以指定类的属性。可以指定属性名、类型、文档、数据库列名、数据库列长度、允许的空值和该属性是否唯一。此外,属性可以是静态的、最终和/或临时的。属性可以定义成受保护的(protected),从而子类和反射代码可以访问这些属性。但是,其它类和应用代码只能通过getter和setter方法访问这些属性。支持以下属性类型:int,boolean,float,long,short,double,char,String,Date,Time,Timestamp,Interger,Boolean,Float,Long,Short,Double,BigInterger,BigDecimal,Character,Object,byte,Byte,char,Character,EncryptedString,HashedString和TranslatebleString。
这些类型可以适当地影射为Java基本类型,后者可以映射为特定于数据库的类型。Object,byte,Byte可以映射为数据库中的BLOB类型以存储字节流。char,Character可以映射为数据库中的CLOB类型以存储大的字符流。EncryptedString,HashedString类型是特殊类型,它们只是字符串,但所产生的代码在设置属性前会加密/哈稀(hash)该值,并且该代码会在通过getter和setter方法返回该属性时解密该值。TranslatableString属性也仅是一个字符串,但所产生的代码也产生一个附加表,其中的列代表该属性的翻译值。这使得要指定的类的特定属性显示出该属性的多个翻译值可以为支持本地化存储在数据库中的对象值而存在。
然后可以指定类的关系。在UML中,采用具有从一个对象到另一个对象的箭头的直线来指定关系或关联。该关联的每一方都称为角色。角色名等于该关联的“来源”方的类的属性名。角色应当是受保护控制的(就象属性一样)。每个角色可以指定多样性。支持“0...1”、“1”和“0..*”。“0...1”指定在该角色方的对象的0个或者一个实例可以在该关系中。同样,“1”指定该角色方的对象的恰好一个实例应当在该关系中(通常为代表与该关系来源方的类的关联的列指定非空约束)。同样,“0...*”指定对象的0个或更多实例可以在该关系中。这等价于包含一个关联对象集合的关系。
关系也可以是双向的。这意味着关联的每一方都可以看见另一方。在双向关系中可以存在上面指定的多样性的任意置换。此外,该关系的一方可以显示为集合(在关系的来源方上用开口菱形来表示)。集合关系指定“来源”类专有的“目的”类的实例。从而创建和删除“目的”类的实例是“来源”类的责任。
对象建模程序允许定义可以设置在每个单独的包、类、属性、关系和关系角色上的附加特性。对每种类型的对象,都可以通过对象建模程序将“CBOF”标签添加到属性中,如图3所示。该标签列出可以为每种对象设置的特殊属性。生成对应于可视模型的元数据或机器可读数据的模块可以访问任何对象的任何特性。因此,通过添加特性,可以设置类的附加特性来定制后面代码的产生,以及对该类的其它支持。
具体地说,Rational Rose对象建模程序允许添加包含用于各种对象的附加特性值的扩展。在创建对象模型时(具有诸如类、属性、关联等特征),可以在这些对象模型上指定和/或设置一组特性。该组特性可以为了定制的目的而扩展和添加。图4示出添加到弹出窗口中用于指定类特性的CBOF标签401。可以选择402特性集合或特性子集来操纵。对于模型特性,存在特性名称41l、值412和来源413(例如显示为默认或覆盖)。控制用户来操纵这些特性。具有非默认值的特性是粗体、高亮显示或着重显示。
下面的描述列出可为各种类型的对象添加的特性,以及一个或多个用于控制代码的产生和对类的其它支持的方式:
1.Project Properties(项目特性):认为一个对象模型是一个“项目”。因此,可以设置一些对于整个对应项目对象是全局的特性。
CopyrightNotice(版权通告)-覆盖以生成的代码输出的版权通告。
ProjectName(项目名称)-覆盖将被生成的OR映射项目类的类名。
ProjectDescription(项目描述)-设置将作为静态变量存储在生成的OR映射项目类中的描述。
2.Class Properies(类特性):一个类可以包括根据类图创建的一个UML类对象。通过点击一组标准特性,可以添加称为“Cmo”的新标签,其具有下列特性:
Generate(生成)-设置为“否”来避免为只为存档目的而存在的某些类生成代码。
GenerateEJB-设置为“是”来生成与类的一个或多个EJB接口。
TableName-覆盖类的默认表名。在默认情况下,该大写类名的前面27个字符可以是表名。
IsStageable-设置为“假”来避免为该特定类生成任何分段能力,如下面将要详细描述的。
MaxNumVersions-设置为大于0以设置过去变化的数目,以保持特定的类实例。
ReplaceClass-指定该类实现所代替的现有类的全路径类名。
WrapperPackageName-指定生成外壳(ImplC)类的包名。
ImplPackageName-指定生成持续实现及其主要外壳(Impl和ImplW)类的包名。
StageablePackageName-指定生成持续可分段实现(ImplS)的包名。
Constraintl至Constraint7-指定对一个类的表层约束。例如“UNIQUE(name,owningMember)”。
IsDisplayed-指定是否需要在给定用户界面中将类名显示给用户。
DisplayName-覆盖该类的默认显示名。在默认情况下,类名是通过消除任何“Cmo”前缀然后在后面紧跟着小写字母的大写字母处插入空格来生成的。
DisplayDescription-设置应当为该类显示的描述。
3.Attribute Properties(属性特性):可以为上述基本类型的属性在特定类中添加属性。属性可以具有称为“Cmo”的新标签,具有以下特性:
ColumnName-覆盖该属性在用于该属性类的表中的默认列名。在默认情况下,用‘_’来分隔字边界的大写属性名的前面30个字符可以是列名。
I18NConstraintName-覆盖为该列添加的_IN表的默认约束名(如果该属性设置为唯一)。
4.Association Properties(关联特性):关联可以添加在两个特定类之间。关联可以包括两方,它们被称为角色。关联本身可以具有称为“CBOF”的新标签,具有以下特性:
RelationTableName-如果关联代表多对多或单向一对多关系,则可以添加中间或“关系”表。设置该特性以指定关系表名。默认情况下,该关系表名试图取该关系双方的类名并在中间使用“TO”。如果该名称太长(超过27个字符),则使用后面跟着该类名的字符串杂凑码的类名首字母(字边界的首字母)。
5.Role Properties(角色特性):角色代表关联的一方。一个关联具有角色方A和角色方B。因此,如果向角色对象添加特性,则可以向关联特性添加两个附加标签,即“CBOF A”和“CBOF B”,具有如下特性:
ColumnName-覆盖该关联在该关联类的表中的默认列名。默认情况下,用‘_’来分隔字边界的大写角色名的前面30个字符可以是列名。
GenerateForeignKeyConstraint-设置为“假”,如果不应当为关联的这一方生成外来关键字约束的话。
ForeignKeyConstraintName-覆盖关联这一方的默认外来关键字约束名。
如下面讨论的,水平分割可以作为项目特性来分配以包括一组对象,或作为类特性来分配以包括相关对象。一旦所有的类、属性和关系都已建模,代码就生成了。
也可以指定操作,并将这些操作的特性分配如图5所示。示出CBOF附加项标签501。至少两个特性521是可以被访问的,其表示是否生成EJB本地接口和/或EJB远程接口。对于每个特性都示出名称511、值512和来源513。更概略地说,本地接口以较小的开销遵循第一协议,适用于驻留在同一web容器121或同一包中的调用和被调用的对象。远程接口以较大开销遵循第二协议,适用于远程方法调用。远程方法调用协议是为诸如CORBA,JavaRMI,MicrosoftTransaction Server,Microsoft COM/DCOM,Microsoft.NET Framework和Enterprise JavaBeans(EJB)的规范和产品而提供的。生成本地和远程接口的选择控制调用开销和/或接口的外露。
图6示出可以用于EJB封装的CBOF模型。参考图6,根据本发明的实施例示出对象框架610的框图。在替代实施例中,对象框架610可以已经包括各种其他组件或配置,以补充或替换那些结合图6的实施例讨论的组件。
COF/CBOF实现的有用方面包括下列组合:将Rational Rose用于建立对象的模型,但不限制于对象模型设计;为定制的业务逻辑方法产生具有占位符或短划线的代码;产生代码来支持对象的运行时创建、读取、更新和删除(CRUD),而无需采用Rational Rose的反向工程;除了用户声明映射参数之外,以少量或没有用户交互地进行对象到关系(OR)映射;生成持续映射信息以便将业务对象持续(persist)到关系数据库;定义和创建关系表和约束,包括需要用于创建数据库模式的信息和使用该信息创建和/或移植数据库的工具;可通过一组标准API访问的、用于运行时创建、读取、更新和删除(CRUD)的简单方法,从而能容易地在该框架内创建、读取、更新和删除任何业务对象。使用事务范例来创建、更新和删除一组使用该数据库中原子事务的对象。事务的寿命可以很长,因为数据库直到交付时间之前还未受到影响并且使用了优化锁定。数据分段,以支持在不影响该对象的现有生产版本的情况下改变业务对象,直到测试、批准和配置该改变;数据变化历史支持,包括任何对象的基本属性变化的监听跟踪;产生代码和信息来创建可用于透明存储和挽救业务对象的可翻译字符串属性的数据库模式;支持在运行时动态地向任何对象添加新属性,而不影响该数据库模式;支持对象变化通告,包括将业务对象配置为具有在创建、更新或删除该对象时生成的事件的选项,这些事件持续到数据库,并且可以通过事件通告服务来管理,而且在业务对象首先在存储器中构建之后(init(),在插入数据库中之后(postInsert()),在添加到用于更新的事务中之后(postAddForUpdate()),在事务中更新到数据库之前(preCommit()),在从数据库加载/刷新之后(postRefresh()),最后在从数据库中删除之前(preDelete()),该业务对象本身也可以实现执行某个动作的方法。
在图6的实施例中,一组5个基本类显示在横轴614之上,并且可以优选地包括基本活跃对象类CmoBaseImpl630、基本接口类CmoBase634、基本分段类CmoBaseImplS638、基本国际化类CmoBaseI18N642和基本外壳类CmoBaseImplW644。这些基本类的功能和使用概略性地描述在通过引用而合并的申请中。
在图6的实施例中,一组根类显示在横轴614和横轴618之间,并且可以优选地包括从前面的对应基本类继承而来的各个根类。在图6的实施例中,根类可以优选包括根活跃对象类AbstractXImpl646、根接口类AbstractX650、根分段类AbstractXImplS654、根国际化类AbstractXI18N658、根外壳类AbstractXImplW662、根定制类AbstractXImplC666。
在图6的实施例中,一组子类显示在横轴618之下,并优选包括从前面的对应基本类和根类继承而来的各个子类。在图6的实施例中,子类优选包括子活跃对象类XImpl670、子接口类X674、子分段类XImplS678、子国际化类XI18N682、子外壳类XImplW686和子定制类XImplC690。
此外,在图6中,上面引用的接口类系列显示在纵轴622的左侧。外壳类系列显示在纵轴622和纵轴626之间。此外,持续存储在数据库120中的一组类显示在纵轴626的右侧。接口是外露给该系统用户的公共Java接口。这些接口定义获得、设置、添加、删除和定制业务逻辑的方法。这些接口还包含API的java文档以供参考。生成这些接口,并且不能手动修改,因为手动修改不会允许重新生成后面的代码。
在一个实施例中,这些类与作为软件组件的TopLink交互。尽管后面的解释是特定于TopLink的,但是本领域的技术人员应当理解相同的方法可以用于其它数据库映射和管理模块。持续类是描述给TopLink的实现类,作为包含持续属性和映射到关系数据库的类。三种持续类包括Impl,ImplS和I18N。Impl类代表数据库中的对象的确切有效版本。ImplS类代表数据库中的有效对象的遮蔽或分段版本。在接口类中描述的所有获得/设置/添加/删除方法都在这些类中实现。所有业务逻辑API都抛出UnsupportedOperationException。I18N类包含可翻译的字符串属性和翻译场所。Impl和ImplS类与I18N类是一对多的关系。无论何时调用可翻译字符串属性的获得/设置方法,都根据在线程上设置的当前场所访问I18N类的适当实例。生成这些类并且不能手动更改。
外壳类实现事务支持、分段、变化历史和定制业务逻辑功能。存在两类外壳类:ImplW和ImplC。ImplW类是一种抽象类,其只实施来自接口类的获得/设置/添加/删除方法。这些方法适当地检查是否检索或设置Impl对象、ImplS对象或它们的合适TOPLink事务复制品的值。设置/添加/删除方法抛出CeNotInTransactionException,如果没有因为事务中的更新而添加该实例的话。如果试图访问在事务之外的克隆外壳,则获得方法将抛出具有“访问了无效外壳”消息的CeRuntimeException。当访问或创建任意持续对象时,ImplC类是实例化的具体类。该类从对应ImplW类继承而来。ImplC类可以手动修改,以包含任意定制业务逻辑方法的实现。ImplW类随着每次重新生成而完全产生。ImplC类通常生成一次,然后作为可以保持的个性化文件而加入源控制。注意ImplW和ImplC类的继承结构。ImplW类从其超类的ImplC继承而来。ImplC从其对应ImplW类继承而来。还要注意ImplW不实施在接口类中描述的业务逻辑API。这些API由ImplC类实现。类可以抽象地在模型中声明,这会使得ImplC类抽象。
还要注意持续类和相关TOPLink事务复制品可以引用其对应外壳。TOPLink缓存中的持续实例指向其外壳的只读版本。复制品指向其外壳的可写版本。当给出了复制品并合并到TOPLink的缓存实例中时,对应外壳变成无效。复制品的外壳可以引用其对应的只读外壳,并且这可以通过对该外壳调用getReadOnlyObject()方法来获得。
需要基本类的层次来描述该文件组。图6示出该基本类层次的实施例。在图的顶部存在5个基本类:CmoBaseImpl630,CmoBase634,CmoBaseImplW644,CmoBaseImplS638,CmoBaseI18N642。
CmoBase634是所有对象332都从它继承而来并实现的接口类。该接口包含所有对象332都必须实施的所有基本属性和操作的描述。该对象框架610的各种特征包含添加到该接口中的属性和方法,从而可以在所有对象中实现这些属性和方法。CmoBase634还用作标记由该框架内提供的机制生成的对象332的途径。可以提供替换类CmsBase702,如图7所示,用于不需要持续的临时对象。
CmoBaseImplW644代表包括将对其它实现对象(CmoBaseImpl,CmoBaseImplS,CmoBaseI18N)的访问进行包装的实现外壳对象。CmoBaseImplW类实现CmoBase接口。CmoBaseImplW类的目的是确定Impl(对于活跃对象)或ImplS(对于分段对象)的哪一个实例应当被调用来实施操作。该类具有4个重要关系。liveObject具有CmoBaseImpl对象的实例,后者代表数据库中的主要活跃业务对象。shadowObject具有CmoBaseImplS对象的实例,后者代表数据库中活跃业务对象的遮蔽或分段版本。当clonedObject放入用于创建或更新的事务中后,该对象拥有liveObject或shadowObject的复制品。当clonedObject包含shadowObject的复制品时(这发生在为了在事务中更新和创建而分段该对象时),liveClonedObject拥有liveObject的复制品。
liveObject具有只读外壳。通过向事务添加只读外壳可以使外壳可写,这返回一个新外壳,包括可以在不影响其它正访问liveObject的用户的情况下被修改的liveObject的复制品。当提交事务时,该复制品用于向数据库发送更新,并将这些变化合并到liveObject中。一旦提交了可写外壳,该可写外壳就不再有用,并且必须访问只读外壳(这使得可写外壳成为垃圾以节省存储器)。当实施任意动作(创建、读取、访问关系和更新)时,该类的实例返回给用户。
CmoBaseImpl630代表数据库中的活跃持续对象。该类包含控制对象与关系映射的特性。这种信息允许创建包括表、列、约束在内的格式。该类包含在对象模型中定义的属性,包括代表关系(或者是具有该对象类型的单一关系或者是采用集合类型的多关系)的属性。该类还实现CmoBase接口634。实施属性与关系的获取和设置,以访问有关的属性或关系。其他业务逻辑方法(在模型中描述)抛出UnsupportedOperationException来防止对该方法的意外访问。只有ImplW类应当访问该类,并且它不应当调用对Impl类的任何业务逻辑方法。
CmoBaseImplS638本质上就是CmoBaseImpl类的复制品,但代表Impl实力的遮蔽或“分段”值。这些分段值存储在一个单独的表中,并且是单独的实例,因此提供了一个单独的类来代表映射到该单独表的分段。CmoBaseImplS638的使用还在通过引用而合并的申请中进行了讨论。
CmoBaseI18N642是用于国际化支持的基本类。该类拥有所有具有可翻译字符串值的表都需要的基本属性。当生成对象的Impl类时,从CmoBaseI18N642继承而来的内部类也被生成,如果该类具有可翻译字符串属性的话。CmoBaseI18N 642的实例对应于Impl类的可翻译字符串属性的语言翻译。为该翻译的分段值提供了附加实例。翻译列表保存在类分层的每一级。这使得可以随时添加/删除可翻译字符串属性,而无需CmoBaseI18N类和表的分层结构。这些特征更详细地记录在通过引用而合并的申请中。
当生成对象时(例如AbstractX646),所生成的类扩展了合适的基本类。如图6所示,AbstractX646是从CmoBase基本接口继承而来的接口。AbstractXImplW 662从CmoBaseImplW644继承而来。AbstractXImpl646从CmoBaseImpl630继承而来。AbstractXImplS654从CmoBaseImplS638继承而来。此外,由于存在AbstractX的可翻译字符串属性,AbstractXI18N658从CmoBaseI18N642继承而来。
还存在另一个称为AbstractImplC666的定制类,其从AbstractXImplW662继承而来。ImplC类包含用于添加到模型中接口的业务逻辑方法的特定于用户的业务逻辑代码。这允许ImplC只能生成一次,然后只能在需要添加、更改或删除业务逻辑代码时更新。其它类的类型(接口,ImplW,Impl,ImplS,I18N)总是在每次模型变化时从对象模型320中重新生成。这解决了生成需要手动定制任意需要反向设计到模型中的更改的代码,但还允许写入可以随着时间的过去而改变的业务逻辑实现。所生成的代码在不需要任何可写入ImplC中的代码的情况下就可以使用。ImplC为待实现的特定于用户的业务逻辑方法提供了场所。
此外,图6示出另一个称为X的类如何能进一步扩展AbstractX类。X的每个生成类的类型都从AbstractX的适当类类型继承而来。然而,XimplW686从AbstractXImplC666继承而来,从而XimplC686的实施可以覆盖AbstractX类的任何业务逻辑方法,就好像该类已经是直接子类那样。本发明的一个方面是自动处理用于管理这些类之间关系的继承结构和代码的复杂性。直观上,用户只需要关心可视建模的对象和ImplC中的业务逻辑代码实现。
图7是示出用于支持EJB和J2EE的类CmoBase701,CmsBase702,CmoAttribute703的方面的类图。持续的、用户可更改的对象从CmoBase701继承而来。但是,很多属性可以是临时的并且不能由用户更改,因此它们的静态值可以分配给存储器中创建的对象的工作复制品。这些临时属性可以从CmsBase702继承而来,后者具有适用于临时性的特性和属性。在属性级的持续、用户可更改对象包括名称、描述、版本最大数、通知行为。CmoBase类701包括主要关键字,即自动生成的“id”。ID对一个DB和类型内的一行来说是唯一的。因此,完全和全局唯一的ID连接数据库标识符、类型和ID字段。该连接的唯一标识符满足唯一ID的当前EJB2.0的要求。连接的唯一标识符还用于下面讨论的水平分割,因为CmoBase701中的ID只保证在一个数据库和类型中是唯一的。CmoBase701的附加属性包括所示出的状态、版本化和分段属性。如图10所示,构造从CmoBase继承而来或对应于该类的CmoBaseLocal和CmoBaseRemote类。CmoAttribute703支持为对象定制属性,如通过引用而合并的申请中所描述的。
图8-10示出COF工具和模型用于EJB和J2EE支持。优选地,系统中的业务对象接口应当从图10的javax.ejb.EJBLocalObject1013扩展出。该扩展模式提供了在同一Java虚拟机器(JVM)中运行的EJB对象上调用方法的途径,而不会导致与远程访问相关的开销。每一个需要被远程访问的业务对象要求名称与本地接口相同、并放置在“ejb”包下的单独接口。远程接口扩展了avax.ejb.EJBObject1012并只包含能被远程访问的方法。除了本地和远程接口之外,ejb说明需要家用接口来创建和找到ejb对象,如图9所示。每个业务对象具有扩展javax.ejb.EJBLocalHome911的本地家用接口912以及扩展javax.ejb.EJBHome901的远程家用接口902。
包含实施业务逻辑的代码的bean类通常通过对接口名称添加后缀“ImplC”来命名。例如在图8中,PersonImplC842和EmployeeImplC862是意欲包含对应于Person和Employ接口821、841的业务逻辑的对象。不是“ImplC”中的所有业务方法都可以远程访问。远程方法通过将本地方法的参数和返回值设置为可序列化(为了符合EJB必需这样做)来实施。为了实现这一点,框架在可以实施附加远程业务方法的地方生成具有后缀“Bean”(例如PersonBean)的类。除了提供业务逻辑实施之外,还实施多个特定于EJB的回答。这些回答通过实施CmoBaseImplW类(图6中的644)中的javax.ejb.EntityBean接口1011来提供给持续对象。用于提供EJB功能的回答包括ejbCreate(),ejbPostCreate(),ejbFindByPrimaryKey(PrimaryKey key),ejbLoad(),ejbStore(),ejbRemove(),ejbActivate(),ejbPassivate(),setEntityContext(EntityContext ctx)和unsetEntityContext()。在这些回答中,当客户机在家用接口上调用create()方法时调用ejbCreate()方法。Ejb容器创建bean(ImplC类)的实例并在该bean上调用ejbCreate()方法。实施应当提供方法来用于:获取或创建CmoTransaction;向该事务添加该bean;初始化外壳对象;预先分配对象ID;提交事务;返回PrimaryKey对象。在很多情况下需要超载该方法,以便在非空数据库约束中通过初始化对象所需要的参数。
该容器在调用ejbCreate()方法之后立即调用ejbPostCreate()方法。该方法应该和ejbCreate()具有同样多的论点,并提供附加初始化并分配在其寿命内需要的资源。
当客户机在家用接口上调用findByPrimaryKey()时调用ejFindByPrimaryKey(PrimaryKey key)方法。该实现应当提供方法来用于:指示不需要事务;根据对象id在数据库中找到该对象(采用CmoClientSession.findById()方法);并返回PrimaryKey对象。该方法对定制查询需要超载。
ejbLoad()回答方法大致对应于实体bean的“读取”功能。在实现本发明方面的实施例中,通常在create()或find()方法期间采用TOPLink OR映射来初始化该bean,因此该方法可以用于某些后处理操作。
ejbStore()回答方法大致对应于实体bean的“更新”功能。该功能已经封装在我们的CmoTransaction中,除了CmoTransaction需要被启动以及为了更新需要将该对象添加到该事务中这个事实。
ejbRemove()回答方法从Data Store中删除了该对象。CmoTransaction被启动并为了删除而添加到该对象中。
在激活处理期间,在bean实例上的ejbActivate()方法被调用,后面接着EjbLoad()方法。一旦bean被激活并且其状态被恰当的与底层数据库记录同步,则业务方法继续。任何随后对该业务方法的调用都直接委托给bean实例。
ejbPassivate()在钝化期间使用。在钝化处理期间,容器在bean实例上调用ejbStore()。Bean实例负责更新数据库。在数据库更新后,容器在bean实例上调用ejbPassivate()方法,让自己有机会在钝化bean前释放任何先前被分配的资源。
在bean初始化期间用bean的语境调用setEntityContext(EntityContext ctx)方法。该语境存储来用于将来的应用。unsetEntityContext()补充该设置语境。如果容器决定释放由bean使用的资源,则容器可以象收集垃圾那样来收集合并的bean,并且在这种情况下事务会返回不存在的状态。在该转换方法中,容器调用该方法。该方法释放由该bean使用的任何资源。
图8示出兼容EJB的CBOF对象模型应用于人员和雇员的简单对象,其具有本地和远程访问和接口。Person821、824和Employee841、834对象从EJBLocalObject811heEJBObject814实施而来。本地对象的实施支持本地的、减少了开销的访问。EJBObject的实施支持远程对象访问。本地对象的标准特性是从CmoBase812继承而来的,如上所述。在图8中,后缀ImplW和ImplC都用于外壳和创建实施。EntityBean813通过CmoBaseImplW822来实施。Person821和Employee841对象的实施从CmoBaseImplW822继承而来。这些实施包括PersonImplW832,PersonImplC842,EmployeeImplw852和EmployeeImplC862。如图9的上下文中讨论的,为本地和远程接口提供两个家用对象EJBLocalHome853和EJBHome833。这些家用对象的实施包括PersonLocalHome863,PersonHome843,EmployeeLocalHome864和EmployeeHome844。
图9概括了图8的一部分,并示出与需要给对象一个住所的常规EJB兼容的例子。为远程和本地对象和接口901、911分别提供了场所。每个业务对象具有扩展了javax.ejb.EJBHome 901的远程家用接口902和扩展了javax.ejb.EJBLocalHome911的本地家用接口912。远程和本地家用接口902、912还通过CmoApplicationConfigRemoteHome903和CmoApplicationConfigLocalHome913来扩展。
图10也概括了图8的一部分,并示出支持EJB的附加机制。对象javax.ejb.EJBObject1012和javax.ejb.EJBLocalObject1013扩展到CmoBaseRemote1022和CmoBaseLocal1023。
EJB2.0说明支持EJB实体间的关系。3个基本关系基数(一对一、一对多和多对多)都受到支持。此外,可以采用EJB2.0说明的新查询语言来操纵这些关系。关系可通过抽象访问器方法来管理。在相关对象的多样性是多的关系中,抽象访问器的参数或返回值类型是代表该关系的集合类。该集合类实施java.util.Collection或java.util.Set接口。可选的,这些说明可以添加java.util.Map和java.util.List作为返回类型。在集合类的多样性是一的关系中,抽象访问器的参数或返回值类型是有关对象的单一实例。
COF中的关系访问器具有作为对应对象数组的参数或返回值类型。为了使得它们可以通过远程接口被ejb访问,应当在远程接口中提供关系的附加方法并在ImplW中实施。例如,Employee To Address Relationship可以是一对多并且是双向的。本地和远程方法可以实施为横越一个关系,如Employee To AddressRelationship例子。例如,本地方法可以包括:public Address[]getAddresses();public void setAddresses(Address[] address);public voidaddAddressElement(Address address);和public BooleanremoveAddressElement(Address address)。远程方法可以包括可以包括:publicCollection getAddressesRemote();public void setAddressesRemote(Collectionaddress);public void addAddressElementRemote(Address address);和publicBoolean removeAddressElementRemote(Address address)。getAddressesRemote()方法支持获取与Employee对象相关的所有地址对象的objectId列表。可以采用CmoQueryCursor机制,因为不需要缓冲任何地址对象。因此,从CmoQueryCursor扩展的、称为CmoObjectCursor的新类被创建,以支持EJB实例的远程指示。该方法支持利用远程家用接口找到或创建ejb对象,并把它们存储在集合中。该方法返回ejb对象的集合。setAddressesRemote(Collection address)方法支持利用本地家用接口创建或找到对应的ejb对象。该方法将对象存储在数组中。该方法调用对应的本地方法来更新。
事务支持是由J2EE平台提供的重要基本服务。该说明描述了JavaTransactionAPI(JTA)。JTA是提供访问底层事务管理器的接口。一些主要接口包括:javax.transaction.UserTransaction和javax.transaction.TransactionManager。UserTransaction外露给应用组件,而J2EE服务器和JTATransactionManager之间的底层交互对该应用组件是透明的。TransactionManager实施支持服务器对(容器区分的)事务边界的控制。JTA TransactionManager和JDBC的事务支持对J2EE应用组件来说都是可利用的。J2EE平台支持两种事务管理范例:陈述性事务区分和计划性事务区分。在陈述性区分中,容器负责启动、提交和回滚事务。容器对用户在bean上的每个操作都启动一个事务。客户机可以获取JTA事务并执行一个事务中的若干操作。这将提供加强在操作之间具有依赖性的某个业务逻辑的灵活性。事务属性支持陈述性事务区分,并向容器传达有关EJB组件方法的计划事务行为。
对容器管理的事务区分支持6个事务属性:Required,RequiresNew,NotSupported,Supports,Mandatory和Never。具有Required事务属性的方法在JTA事务中执行;根据情况,可以或不可以创建新的事务语境。如果调用组件已经与JTA事务关联,则容器将调用在所述事务语境中的方法。如果没有事务与调用组件关联,则容器将自动创建新的事务语境,并试图在该方法完成时提交该事物。据有RequiresNew事务属性的方法在新事务语境中执行。如果调用组件已经与事务语境关联,则创建新事务语境,该方法在新事务语境中执行,该方法完成后重新开始该调用组件的事务。具有NotSupported事务属性的方法不是事务的一部分。如果调用组件已经与事务语境关联,则容器暂停该事务,调用不与事务关联的方法,并在该方法完成时重新开始调用组件的事务。具有Support事务属性的方法支持调用组件的事务状况。如果调用组件没有任何事务语境,则容器将执行该方法,就好像其事务属性是NotSupported。如果调用组件已经与事务语境关联,则容器将执行该方法,好像其事务属性是Required。具有Mandatory事务属性的方法从该调用组件的事务语境中被调用。否则,容器将抛出javax.transaction.TransactionRequiredException。具有Never事务属性的方法绝不应当从调用组件的事务语境中被调用。
计划事务区分是应用代码内的事务管理的硬代码。计划事务区分对会话EJB,servlet和Jsp组件是可行的选项。计划事务可以是JDBC或JTA事务。对于容器管理的会话EJB,可以(尽管丝毫不推荐)混合JDBC和JTA事务。
本发明的一个方面是可以分段生产数据。为了解决不在数据库中作重复工作的问题,一个实施例将该数据的分段值存储在与有效生产值相同的数据库中。但是,这种分段值不应当存在于与有效生产值相同的表中。如果分段数据在相同的表中,则表的性能和大小都会受到影响。因此,对于每个需要分段能力的对象,数据库中可以存在两个表。由于然后需要附加表,因此OR映射工具需要另一个Java类来代表该表。对于可分段的Impl类来说,存在对应的ImplS类。由于和表格式创建一起自动处理类结构和OR映射,因此需要添加附加表和/或类的努力实际上被减小了。
将现有的对象属性复制到新对象中通常是很直接简单的。但是,分段可能还支持对象之间关系的改变。为了支持所有分段特征,需要定义若干规则:
1.活跃生产对象实例可以引用其分段实例。在某个时间对象只能被分段一次(换句话说,该对象与其分段实例之间的关系是一对一的双向私有关系)。
2.一旦将对象分段,就不能修改其有效实例。如果可以更改该有效实例,则需要将分段值中进行的变化与有效值合并。通常,变化需要被分段或直接在活跃对象上修改,不能两者都进行。
3.关系是针对有效实例,而不是针对分段实例。否则,很多关系映射就必须得到管理(有效对分段、有效对有效、分段对有效和分段对分段)。此外,当对象从分段变到有效或反之,只针对该对象的关系需要管理该变化。该规则简化了这些问题。此外,被引用的有效实例可以分段,并引用其分段实例,因此实际上仍然支持了各种关系,但不是直接的。
4.分段变化必须是可分段项目的一部分。管理一组分段变化的方法是将它们组合在同一容器中。可分段项目跟踪已经分段的所有对象。然后可以配置该项目来用于测试,或删除之。
5.在某个时间对象只能被分段一次,并且是单一可分段项目的一部分。管理合并一般也不需要。
支持一对一关系在分段表中由于上述规则#3是很容易的。所有关系都指有效实例,因此指向另一对象的分段表列只需要指向该另一对象的有效实例。一对多关系必须使用中间关系表,即使该关系是双向的。这防止了活跃对象表必须了解与分段实例的任何关系。
多对多关系还具有将分段实例链接到有效实例的中间关系表。这些中间关系表必须与现有的活跃对象关系表不同。如果多对多关系是双向的,则需要创建两个中间关系表,一个用于每个方向。这是因为该关系可以从该关系的任何一方被分段,并具有不同的值。附加关系表自动和有效的生成。
本发明的其他方面是在中间层的水平分割,如与所谓的后备办公室即数据库层相对的。图11概略示出水平分割。在该例中,对象模型包括组件1(1101)到n(1102)、账户1102和BI1104。组件1映射到主1111数据库,后者是单一数据库。通过在数据库之间被水平分割,组件n映射到主1111和主1112数据库。组件n可以是单一对象或一组对象。用于包并指定将该组对象进行水平分割的工具可能很有用。上面描述了这种用于设置项目特性的工具,并且对于Rational Rose的用户来说是很熟悉的。或者,可以提供用于将对象分配给一组或多组、然后设置不会被覆盖的组默认特性或组全局特性的工具。在任何一个实施例中,作为单一设置的结果使一组对象受到(或不受到)水平分割是很用的。组件1...n的映射在该例中可以通过数据库说明来配置。诸如用户完成的表或用户可读(例如XML)配置文件的说明方法可以用于指定数据库的逻辑名称和/或将数据库的逻辑名称与对象和对象组连接。在该例中,账户和BI已被分别映射到安全1113和BI1114数据库。
支持在中间层进行水平分割的类适用于与数据库或数据基本结构的接口,在本例中适用于与TopLink的接口。图12示出可以用于在中间层实施水平分割的类。该图在左顶端以CmoServerSession1221开始是很容易让人理解的。该对象具有该基本结构需要的数据库连接和信息。由于数据库的逻辑标识是静态的,因此该对象可以具有静态数据和静态方法,并可以由多个用户共享。CmoSystemSession1231可以从服务器会话1221中获得。只需要为服务器创建单一的系统会话对象,CmoClientSession对象1241具有针对该服务器的每个用户的语境和状态信息。该对象具有特定于用户的信息,例如用户的场所和注册。保持类似于为HTTP会话保持的状态信息的状态信息。方法getDb和setDb用于设置语境信息。客户机会话可以涉及若干数据库。客户机会话1241和任何活跃数据库会话1242之间的关系#dbClientSessions是0...*关系。当获得客户机会话时没有数据库客户机会话是有效的。在客户机会话的生命期间,很多数据库客户机会话可以变得有效。
在该图中的CmoTransaction 1251对象缓存将被水平分割的数据。CmoTransaction的角色是保持事务的状态,包括寿命很长的事务,直到该事务准备好提交为止。由于汇集该事务,因此收集允许新的或修改后的对象属于哪个数据库的决定的信息。当该事务准备好提交时,其可以在一个或多个数据库中由CmoDatabaseTransaction 1252的一个或多个实例提交。
水平分割支持,包括中间列对象1212、1222、1232、1242和1252可以添加到基础接口1223、1243、1253的现有排列以及外露的会话1221、1241、1251中,而不会改变这些会话外露的方式或改变这些会话外露的对象可操作业务逻辑。例如,水平分割可以用于支持两个使用相同代码和软件的汽车制造商F和G。用于F的所有数据都可以例如被分割为Oracle数据库,所有用于G的数据可以被分割为SQL数据库。一旦例如在用户登录时设置了语境F或G,数据的分割对系统来说就是透明的。所有对F数据的调用都针对Oracle数据库进行,而所有对G数据的调用都针对SQL数据库进行。可以应用相同逻辑,而不管该数据服务是提供给F还是G。实施业务逻辑的代码甚至可以被共享,因为只有语境设置才识别或区分F和G的数据。在该级上的分割会隔离顾客的数据。较小的数据库可以被更为有效的处理。即使在后备办公室即数据库服务器级,F进行的搜索也决不会考虑G的数据。以SQL、QL或其它数据库查询代码的混合不会从多于一个数据库中返回数据,这会减小一个顾客获得访问其他顾客数据的机会。这在竞争状态中特别有用,例如当原告和被告的律师共享数据库的某些组件但希望将他们的工作产品严格隔离开,或者当竞争者使用添加了相同值的服务并且服务供应商希望确保两个顾客(竞争者)的数据都很安全。顾客的数据与其它顾客隔离开来的同时,周期维护功能可以通过在多个顾客语境中重复说明的系统管理员来完成。
中间列对象1212、1222、1232、1242、1252支持基于语境对多个数据库的访问,其中多个数据库存储相同对象的水平分割的实例。
CmoDatabaseServerSession对象1222为每个在服务器上有效的数据库而存在。数据库通过逻辑名称而逻辑的识别给CmoDatabaseServerSession对象1222,该逻辑名称可以作为该对象的关键字属性dbName保持着。getAllVersions方法支持版本管理。该方法可以返回在数据库中的对象的版本或格式版本。访问数据库的代码或授予访问该数据库的代码应当检查版本是兼容的。
CmoClassConfiguration对象1212将对象连接到数据库。CmoClassConfiguration对象1212代表数据库中可访问的对象。CuDatabaseConfig1232具有对应于逻辑数据库名称的物理数据库配置信息。该信息可以用于根据语境设置将多个物理数据库连接到一个逻辑名称。CmoDatabaseServerSession对象1222通过#serverSession关系连接到基本对象ServerSession1223。CmoDatabaseClientSession1242用基本对象ClientSession1243管理客户机会话,同时考虑该客户机(在该例中的F或G)的语境。
重新访问CmoTransaction1251的操作,当准备好提交事务时,CmoTransaction用适当的语境设置调用CmoDatabaseTransaction1252。CmoDatabaseTransaction1252连接基本对象1253、例如TopLink中的UnitOfWork,以处理该对象的一个或两阶段提交。
两阶段提交是一种以原子方式提交多个物理数据中变化的事务协议。在一个实施例中,支持两阶段提交的软件组件包括基于JTS的Application Server(任何与J2EE1.3兼容的App Server)、JDBC驱动器(例如Opta2000和Seropto)中的分布事务支持以及数据库中(例如SQL Server和Oracle)的分布事务支持。COF和COF/EJB使用TopLink来支持与基于JTS(Java事务服务)的事务管理器(通常由J2EE应用服务器提供)进行事务融合。两阶段提交的使用是一个选项。两阶段提交的代价很大,因此只在需要时使用。影响多个对象并跨越多个物理数据库的用户事务通常使用两阶段提交事务。当EJB对象和COF对象需要在一个事务中提交时,两阶段提交是合适的。该协议可以与COF对象、水平分割的对象和EJB对象的任何组合一起使用。
注意水平分割不取决于COF或另一协议是被直接使用还是封装在EJB或其它远程方法调用封装中。中间层封装处理在独立数据库之间的水平分割,而不依赖数据库管理器。这可以引用为松耦合的水平分割,因为独立数据库甚至可以是与不同数据库供应商不兼容的数据库。
相对较少的业务逻辑或系统代码也需要改变,以使用水平分割。一些基本规则列表如下。
1.如果在配置文件中,只有一个数据库正在使用,这意味着特性“database.projects”的值是单一的,则该数据库将总是被使用。
2.如果配置文件中存在不止一个数据库,则在执行操作时清楚或含糊地分析数据库信息。清楚分析意思是在CmoClientSession对象和/或CmoTransaction对象上调用“setDb(CuDatabaseConfig)”。CuDatabaseConfig对象通常在系统启动时创建。用于为整个系统获得可用数据库对象的列表。对于特定类,“CmoServerSession.getDbObjectsForClass(Class aCLass)”和“CmoServerSession.getDbObjectsForClass(String aCLassName)”返回“class”驻留的CuDatabaseConfig对象的列表。模糊分析意思是CmoClientSession和/或CmoTransaction对象可以聪明地找到哪个数据库正在受到处理而无需在应用程序代码中特别调用“setDb(CuDatabaseConfig)”,如下所述。
3.当数据信息不能在CmoClientSession和CmoTransaction对象上清楚分析时,会话对象试图采用所涉及的所有对象来分析该信息。如果所涉及的任何对象具有一些数据库信息(非空),则该信息与关联会话对象的数据库信息进行比较。如果用于会话对象的数据库信息为空,则将该数据库信息设置为来自该对象的数据信息;否则如果该信息不同,则给出异常。该逻辑对所涉及的所有对象都继续。为了有助于识别用于操作和/或事物的数据库信息,COF引进了新的接口“CmoDbConflictResolver”。为一个项目配置CmoDbConflictResolver对象。这可以在关键字是:database.Conflictresolver.{full class name of project}={fullclass name that implements CmoDbConflictResolver interface}的配置中进行。
4.在最后可能的时刻调用分析器,意思是如果创建对象,则在试图提交该对象之前不会调用该分析器。这意味着,分析器可以预计该对象的所有属性都是为创建而设置,并能将它们用于确定该对象应当属于哪个数据库。
对于找到的情况,通过表达或属性查询或属性映射查询,从而分析器可以基于正被查询的属性确定针对哪个数据库查询。我们从不支持在一个单一的查询中跨数据库查询。仅当还没有在clientSession上调用setDb以及正被查询的对象已配置为存在于多于一个数据库中才需要这样做。
可以实现CmoDbConflictResolver的途径是使用一些配置信息或其它说明一些对象属性值映射到特定物理数据库的动态数据。这应当尽可能的简单。例如,使用该对象的组织id来确定基于orgId来命名哪个数据库或哪些数据库,从而这是一个单一映射。这些数据库名称是“逻辑”名称,是在配置/安装时确定来用于给数据库一个名称和诸如其位置等的配置信息。因此,因此我们使用的名称是逻辑名称,并代表配置来访问的数据库名称,而不是在数据系统中的实际物理数据库名。
在客户机会话上可得到4个函数来控制数据库信息。它们是:setDb(CuDatabaseConfig);getDb();overrideDb(CuDatabaseConfig);resetDb()。getDb()只返回设置在clientSession对象上的当前数据库;overrideDb(CuDaabaseConfig aNewdb)和resetDb()使用堆栈机制来跟踪clientSession上的数据库信息的变化。overrideDb(CuDatabaseConfig aNewdb)将当前db推入堆栈,并将当前db设置为已进入的“aNewdb”。如果堆栈非空,则resetDb()将当前db设置为堆栈的顶端元素;否则不做任何事。setDb(CuDatabaseConfig aNewdb2)将当前db设置为“aNewdb2”并清空堆栈。因此,如果当堆栈具有一些信息时调用setDb(),则堆栈只是被清空。作为特殊客户机会话的系统客户机会话对象对每个线程基础使用这4个函数。因此在一个线程上的数据库信息与另一线程上的数据库信息无关。
overrideDb(CuDatabaseConfig)和resetDb()函数不能在CmoTransaction上被调用,尽管这是CmoClientSession的子类。
CmoDbConflictResolver API包括:public CuDatabaseConfigresolveCreate(CmoDbResolverinfo aDbResolverInfo)抛出CeDbNameConfiictResolveException;public CuDatabaseConfigresolveFind(CmoDbResolverinfo aDbResolverInfo)抛出CeDbNameConflictResolveException。CmoDbResolverinfo API 包括:publicCmoClientSession getClientSession();public Class getMainclass();public HahMapgetAttValuePairs();public CmoFindObject getFindObject();public CmoBasegetNewlyCreatedObject()。
当开发了实施CmoDbResolverinfo接口的类之后,在CmoDbResolverinfo中的getNewlyCreatedObject()可以用于帮助实施resolveCreate(CmoDbResolverinfo);同样,在CmoDbResolverinfo中的getAttValuePairs()和/或getFindObject()可以用于实施resolveFind(CmoDbResolverinfo)。
从上述描述中,本领域的技术人员很清楚各种系统和方法都可以从本发明的方面和部分中构建而来。一个实施例是本发明的一个实施例,包括生成应用程序开发代码的方法。该方法另外还可以实现为执行该方法步骤的系统或装置。该系统或装置可以包括若干实施例,组合了该方法的步骤、方面、选项和替换实施例。该方法还可以实现为刻有执行该方法步骤的程序的磁介质。开发代码的生成特别是可用于多层的封装业务应用环境。该方法基于面向对象的应用程序设计的对象、关系以及操作的模型。对这些对象、关系和操作的建模可以采用图形工具而可视化地实现。分配给对象、关系和/或操作的特性可以包括表示是否生成与建模对象的接口的第一特性。还包括表示是否生成与指定操作的本地和/或远程接口的第二特性。从该模型中,生成对应于该模型及其特性的机器可读的数据。该数据可以在内模型或输出模型中实现。该模型可以只能由机器识别,还可以由人类识别。机器可读数据用于将模型映射为数据库。在一个实施例中,数据库是关系数据库。采用映射和机器可读数据生成应用程序开发代码。所生成的应用程序代码可以包括持续并访问数据库中对象的代码。还可以包括交换该持续并访问数据库中对象的代码的接口。这与第一特性一致。还可以包括与指定操作的接口,这与第二特性一致。与所述代码和指定操作的接口实际上可以与基于标准的服务器端的组件模型以及远程方法调用协议兼容。替代的,应用程序开发代码可以实际上与Enterprise JavaBean(EJB)标准2.0或更新版本兼容。持续和访问EJB对象的代码可以实际上与由bean管理的持续(BMP)协议兼容。替代的,应用程序开发代码可以实际上与Microsoft的DCOM说明兼容。在本发明的另一方面,面向对象的应用设计可以实际上与统一建模语言(UML)标准兼容。
应用开发代码方法的一个方面包括生成添加定制业务逻辑的方法片段。为了实现本发明的该方面,在修改用于系统的面向对象的模型时生成的代码与包含定制业务逻辑的代码隔离开来,并且当修改面向对象的模型时不应当被覆盖或重新生成。
本发明的另一方面还包括对象和关系的多个第三特性,该第三特性控制映射步骤。这些特性用于将对象和关系映射为诸如关系数据库的底层数据库。这些第三特性可以包括是否支持对建模对象的配置的分段。还包括是否记录建模对象的配置的变化历史。还包括是否动态数组化建模对象中的一个或多个字段以国际化这些字段。与本发明涉及动态数组化字段的方面相联系,持续和访问建模对象的代码可以分析基于指定语言来检索动态数组的哪一个元素。该语言可以由正被处理的对象中现有的数据模糊指定,或由语言清楚指定。
本发明的另一方面是用户可以指定生成哪些应用代码,生成机器可读数据、映射和附加生成的方法步骤可以在没有用户的进一步动作的情况下继续。
本发明的另一方面是一种集合由至少一个支持事务处理的数据库管理器处理的事务的方法。替换的,该方法可以实现为执行该方法步骤的系统或装置。该系统或装置可以包括若干实施例,组合了该方法的步骤、方面、选项和替换实施例。该方法还可以实现为刻有执行该方法步骤的程序的磁介质。该方法可以包括提供通过数据库管理器的事务处理支持访问和持续数据的方法的面向对象框架。另外,还提供实际上与基于标准的服务器端的组件模型以及远程方法调用协议兼容的面向对象框架。基于标准的服务器端的组件模型以及远程方法调用协议的例子包括Enterprise JavaBean(EJB)、分布式公用对象模型(DCOM)和CORBA。集合事务的方法还可以包括接受或缓存针对一个或多个数据库的与事务相关的活动。该接受或缓存可以同时通过面向对象的框架和该面向对象的框架的兼容版本进行。该实施例的一个方面是接受步骤可以包括缓存对象,并且在指示提交事务时,该方法还包括调用数据库管理器来处理事务。该方面包括通过非数据库管理器的机制来接受与事务相关的活动。本发明的该方面可以用上述任何标准实现,包括EJB、DCOM和CORBA。
本发明的其它实施例是一种集合由至少一个支持事务处理的数据管理器机处理的事务的方法。如上所述,该方法还可以实现为方法、装置或包括实施该方法的程序的磁介质。该实施例的替换方法是上述集合方法的近似变形。一种变形包括提供通过数据库管理器的事务处理支持访问和持续数据的方法的面向对象框架。该方法还包括提供适用于与EJB标准兼容的处理和调用的面向对象框架版本。该方法还包括同时通过面向对象框架和与EJB标准兼容的面向对象框架版本接受与事务相关的、针对一个或多个数据库的活动。在该实施例的其他两个变形中,面向对象框架适用于与DCOM或CORBA兼容。在任何一个变形中,接受的东西可能包括缓存对象和在提交事务时调用数据库管理器来处理该事务。
另一个实施例是使由至少一个数据库管理器处理的数据持续的方法。如上所述,该方法还可以实现为方法、装置或包括实施该方法的程序的磁介质。持续数据的该方法包括提供通过数据库管理器访问和持续数据的方法的面向对象框架。还包括提供通过数据管理器访问和持续数据的方法的、与标准兼容的接口。这些与标准兼容的接口可以与EJB,DCOM或CORBA兼容。该方法还包括同时通过面向对象框架和与标准兼容的接口接受针对一个或多个数据库的对象访问和持续请求。当标准是EJB时,对象请求可以由面向对象的框架和与EJB标准兼容的接口提交给Java事务服务引擎。
本发明的可以用于任何上述实施例的方面是面向对象框架适用于将精密的对象持续到数据库中。与标准兼容的接口,包括与EJB标准兼容的接口,适用于将事务中的对象持续到不止一个数据库中。
本发明的另一实施例是集合将由至少一个支持事务处理的数据库管理器处理的事物的方法。如上所述,该方法还可以实现为方法、装置或包括实施该方法的程序的磁介质。该方法包括提供通过数据库管理器的事务处理支持访问和持续数据的方法和实施附加功能的方法的面向对象框架。该附加功能可以是为了测试和添加到生产系统而将对象分段。该附加功能还可以是在生产系统中跟踪对象的变化历史。或者,可以是在对象内将字段进行动态数组化以国际化这些字段。这些附加功能可以成对或全部组合。集合事务的方法还包括另外提供实际上与基于标准的服务器端组件模型以及远程方法调用协议兼容的面向对象框架版本,该版本还包括一个或多个上述附加功能。单独的实施例包括单个附加功能、成对附加功能的组合和全部3个附加功能。集合事务的本发明兼容的标准可以是EJB,DCOM或CORBA。
本发明的另一实施例是一种生成数据库和被水平分割的多层业务应用的方法。如上所述,该方法还可以实现为方法、装置或包括实现该方法的程序的磁介质。该方法包括将对象和关系建模,以及指定面向对象应用设计的操作,其中该对象的特性包括是否水平分割跨多个数据库的对象。该方法可以应用于对象或对象组。对象组可以由一个逻辑名称来表示。该方法还包括生成对应于模型的机器可读数据,包括特性。该机器可读数据可以只能由机器识别,还可以由人识别,如XML说明。该方法还包括将模型映射为多个使用该机器可读数据的数据库,以及另外从该映射和机器可读数据中生成应用开发代码。该应用开发代码包括持续和访问跨多个数据库的对象的代码。持续和访问对象的代码是在数据库层之上的中间程序层的一部分。本发明的另一方面是持续和访问对象的代码可以调用多个独立数据库。这些独立数据库可以由不同的数据库供应商提供,或者尽管由一个数据库供应商提供也可以独立运行。该实施例的另一方面可以包括说明多个在其上分割对象的数据库,以及说明一个或多个用于将对象或对象组分割为特定数据库的字段。
本发明的另一实施例是一种在包括至少数据库层和中间业务应用层的多层业务应用中跨多个独立数据库来水平分割对象的方法。如上所述,该方法还可以实现为方法、装置或包括实现该方法的程序的磁介质。该实施例包括在至少一个被水平分割的对象中说明一个或多个可以用于将特定对象分配到特定数据库的字段。该方法包括建立与多个被水平分割的对象所属的数据库的连接,尽管不需要和被水平分割的对象所属的所有数据库建立连接。在建立连接之前或之后,该方法包括缓存一个或多个有待找到、创建或者有待找到或创建的对象,包括被水平分割的对象。在进行找到或创建时,利用说明的字段来分析该对象所属的特定数据库,并调用数据库层中的该特定数据库,以执行找到或创建。类似的实施例是一种跨多个独立数据库来水平分割对象的方法,包括建立与至少一个被水平分割的对象可能所属的多个数据库的连接。此外,设置或识别水平分割的对象所属的特定数据库。在设置步骤之前或之后,缓存一个或多个有待找到、创建或有待找到或创建的对象,包括被水平分割的对象。在进行找到或创建时,调用数据库层中的该特定数据库以执行找到或创建。被水平分割的对象所属的多个数据库可以共同标以一个逻辑名称。采用被水平分割对象的一个或多个属性来逻辑映射多个数据库中的特定数据库。这些属性可以是该水平分割对象的字段。
虽然通过参考优选实施例和上述例子公开了本发明,可以理解这些例子是为了说明而非限制。计算机辅助处理暗含在所描述的实施例中。因此,本发明还可以实现在用于计算机辅助处理的方法、包括实施该方法的逻辑的系统、刻有实施该方法的逻辑的介质、具有实施该方法的逻辑的数据流或由计算机访问的处理服务。本领域的技术人员可能会想到在本发明的精神和权利要求的范围中的修改和组合。