首页 > 编程语言 >OAF:第五章-实现服务端java实体对象

OAF:第五章-实现服务端java实体对象

时间:2023-07-13 11:31:56浏览次数:35  
标签:OAF java name 对象 create 实体 校验 value 服务端

一、关于实体对象

实体对象:实体对象为应用表封装了业务逻辑和DML操作; 1.对象模型和关键类

  • oracle.apps.fnd.framework.server.==OAEntityCache==:该缓存类用于存储特定实体对象的查询结果集。映射到相同实体对象的多个视图对象共享相同的实体缓存;
  • oracle.apps.fnd.framework.server.OAEntityImpl:
  • oracle.apps.fnd.framework.server.OAEntityDefImpl:
  • oracle.apps.fnd.framework.server.OAEntityExpert:
  • oracle.jbo.Key:

二、新增

创建实体对象,必须在相应的视图对象中先调用createRow,然后调用insertRow方法。如下例所示:

// In the application module; this example from the OA Framework
// ToolBox Tutorial will instantiate a SupplierEOImpl.
public void create()
{
 OAViewObject vo = getSuppliersVO();
 vo.insertRow(vo.createRow());
 // Always call this after you perform a row insert. See the Entity Object
 // New / Initial section below for additional information.
 vo.setNewRowState(Row.STATUS_INITIALIZED);
}

==在视图对象中的CreateRow()方法会调用实体对象中的Create()方法==。可以在实体对象的create()添加默认/初始化代码。 警告:不要放任何初始化逻辑再实体对象的构造器中初始化逻辑应该在create()方法调用super.create(attribute)之后增加。 提示:如果在设计阶段已经确定了默认值,可以在OA扩展中通过设置default value设置默认值。这些值可以被客户定制化。

/**
* In the SupplierEOImpl class; initialize a new supplier.
*/
Public void create(AttributeList attributeList)
{
 super.create(attributeList); 
 OADBTransaction transaction = getOADBTransaction();
 
 // Supplier id is obtained from the table's sequence
 Number supplierId = 
transaction.getSequenceValue("FWK_TBX_SUPPLIERS_S");
 setSupplierId(supplierId);
 
 // Start date should be set to sysdate
 setStartDate(transaction.getCurrentDBDate());
} // end create()

提示:==当设置实体对象属性值的时候,调用 set<AttributeName>(val)而不是 setAttribute("<AttributeName>", val)==,因为查询步骤将被忽略,性能会得到提高。如果想跳过任何编程化的校验,但是仍然执行对于某些属性声明的校验,可以调用setAttributeInternal()。

1.组合实体对象关联

在组合关联中,==BC4J会自动的设置父主键的属性值到子实体对象中。父主键值将会传给子类实体对象的create()作为参数,当调用super.create(attributeList)时,被自动设置==。不需要在子类实体对象中,自己构造父类实体对象的主键。

2.实体对象初始化/NEW STATE

默认情况下,被创建的实体对象是STATUS_NEW行状态,BC4J添加它们到校验和提交监听列表。在这种情况下,任何触发校验和数据库提交序列的事件都包括这些实体对象。 当插入新行数据之后,马上在ViewRowImpl通过==调用setNewRowState(STATUS_INITIALIZED)来绕过以上的行为==,同时会设置任何关联实体对象的状态为STATUS_INITIALIZED。 这样,==BC4J会从事务和校验监听列表中移除相应的实体对象,从而不会被校验和提交到数据库==。只要用户通过调用setter()方法改变了实体对象的属性,实体对象的状态就会变为STATUS_NEW,BC4J就会将它交给校验/提交监听列表。可以在ViewRowImpl视图行实现类手动调用setNewRowState(STATUS_NEW)去改变实体对象的状态。

3.典型新增案例

在单行中,平铺Master/Detail

一个订单中可能包含多行,每行中可能又包含许多的商品。尽管BC4J可以为单行视图对象创建不同的实体对象,这些实体对象是不相关的或者是伙伴关系。如果这些对象中的一个是另一个的子类,你就需要进行干预。这种情况下,需要在实体对象的行实现中加入以下自定义的create()方法,确保正确色父类关键值被设置在底层的实体对象:

// The following is required to support the creating the master/detail line
// and shipment entities that have been "flattened" into a single row in
// POLineShipFullVO with a 1:1 join.
//
// If you don't do this, BC4J will automatically treat them like peers and
// try to set the po header id as the parent key for both entities.
 
protected void create(oracle.jbo.AttributeList nvp) 
{ 
 PurchaseOrderLineEOImpl lineEO = (PurchaseOrderLineEOImpl)getEntity(0); 
 PurchaseOrderShipmentEOImpl shipmentEO = (PurchaseOrderShipmentEOImpl)getEntity(1); 
 
 try 
 {
 // Create Lines EO 
 lineEO.create(nvp); 
 
 // Create Shipments EO 
 shipmentEO.create(lineEO); 
 // Calling this ensures that any personalization default values
// properly set since the OAF normally sets this in the super.create(), but
 // since this is not called in this workaround, we need another method
 // to ensure customer defaults are applied.
 setDefaultValue();
 } 
 catch (Exception ex) 
 { 
 lineEO.revert(); 
 shipmentEO.revert();
 
 if (ex instanceof oracle.jbo.JboException) 
 { 
 oracle.jbo.JboException jboEx = (oracle.jbo.JboException)ex; 
 // Developers have to do the mapping on their own because of the 
override. 
 jboEx.doEntityToVOMapping(getApplicationModule(), new 
oracle.jbo.ViewObject[]{getViewObject()}); 
 throw jboEx; 
 } 
 throw OAException.wrapperException(ex); 
 }
} // end create() 

4.实体对象缓存

一旦创建,BC4J存储实体对象到事务缓存中。这样做的两个好处是:

  • ==在相同根应用模块下的多个视图对象可以共享相同的潜在的实体对象==,这也就意味着其中一个视图对象对实体对象所作的修改,其他引用该实体对象的视图对象马上可以可以看到。
  • 即使视图对象行集合被刷新,待确定的改变将会保存在缓存中。 需要明确的是,缓存的存在是非常重要的,因为会显示的与它交互去执行某些校验行为。比如,执行一个唯一性检查,你必须在实体对象缓存和数据库中查询是否存在副本。下面在缓存和数据库中去检查数据的三个主要方式:

4.1 findByPrimaryKey( )方法

==findByPrimaryKey( )方法可以保证首先在缓存中查询是否存在给定的建和实体对象类型,然后再去查询数据库==。这个方法是很有用的,但是可能不是一个你想用的轻量及方法,因为它会实例化任何在数据中匹配的实体对象,她也会拉去所有的实体对象到内存,而不仅仅是查找的keys。但是这哥方法比较适合用在-校验序列生成主键的时候,你并不想找到匹配的的地方。当你需要调用一个方法匹配一个中间层访问的时候,它也是很适合的。 下面是SupplierEOImpl类描述了该方法的使用:

public void setSupplierId(Number value)
{ 
 if (value != null)
 {
// Supplier id must be unique. To verify this, you must check both the
// entity cache and the database. In this case, it's appropriate
// to use findByPrimaryKey( ) because you're unlikely to get a match,
// and are therefore unlikely to pull a bunch of large objects into memory.
// Note that findByPrimaryKey() is guaranteed to check all suppliers. 
// First it checks the entity cache, then it checks the database.
 OADBTransaction transaction = getOADBTransaction();
 Object[] supplierKey = {value};
 EntityDefImpl supplierDefinition = SupplierEOImpl.getDefinitionObject();
 SupplierEOImpl supplier =  (SupplierEOImpl)supplierDefinition.findByPrimaryKey(transaction, 
new Key(supplierKey));
 if (supplier != null)
 {
 throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT, 
 getEntityDef().getFullName(), // EO name
 getPrimaryKey(), // EO PK
 "SupplierId", // Attribute Name
 value, // Bad attribute value
 "ICX", // Message application short name
 "FWK_TBX_T_SUP_ID_UNIQUE"); // Message name 
 }
 }
setAttributeInternal(SUPPLIERID, value);
} // end setSupplierId()

4.2 手动缓存迭代

也可以==手工执行和findByPrimaryKey( )方法相同的实体对象缓存检查。可以分步选择性的执行相同的数据库检查==。这样做的好处是可以避免实例化不需要的实体对象。下面是教程中SupplierEOImpl类的例子:

public void setName(String value)
{
 // Since this value is marked as "mandatory," the BC4J Framework will take
 // care of ensuring that it's a non-null value. However, if it is null, we
 // don't want to proceed with any validation that could result in a NPE.
 
 if ((value != null) || (!("".equals(value.trim()))))
 {
     	// Verify that the name is unique. To do this, we must check both the entity
     	// cache and the database. We begin with the entity cache.
    	com.sun.java.util.collections.Iterator supplierIterator = 
	getEntityDef().getAllEntityInstancesIterator(getDBTransaction());
 
 	Number currentId = getSupplierId();
	while ( supplierIterator.hasNext() )
 	{
	 SupplierEOImpl cachedSupplier = 
	(SupplierEOImpl)supplierIterator.next();
 	String cachedName = cachedSupplier.getName();
 	Number cachedId = cachedSupplier.getSupplierId();
 
 	// We found a match for the name we're trying to set, so throw an
 	// exception. Note that we need to exclude this EO from our test.
	 If (cachedName != null && value.equalsIgnoreCase(cachedName) && 
 	cachedId.compareTo(currentId) != 0 )
 	{
 	throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT,
 	getEntityDef().getFullName(), // EO name
 	getPrimaryKey(), // EO PK
 	"Name", // Attribute Name
 	value, // Attribute value
 	"ICX", // Message product short name
 	"FWK_TBX_T_SUP_DUP_NAME"); // Message name 
 	}
}
 
 	// Now we want to check the database for any occurrences of the supplier
 	// name. The most efficient way to check this is with a validation view
 	// object which we add to a special "Validation" application module.
 	OADBTransaction transaction = getOADBTransaction();
 	OAApplicationModule vam;
 	// Look to see if the VAM has already been created in this transaction. If not,
 	// create it.
 	vam = (OAApplicationModule)transaction.findApplicationModule("supplierVAM");
 	if (vam == null)
 	{ 
 	vam = (OAApplicationModule)transaction.createApplicationModule("supplierVAM", 
	"oracle.apps.fnd.framework.toolbox.schema.server.SupplierVAM");
	 }
 
 	// Now, we use a lightweight "validation" view object to see if a 
	supplier exists
 	// with the given name.
	 SupplierNameVVOImpl valNameVo =					 
            (SupplierNameVVOImpl)vam.findViewObject("SupplierNameVVO");
	valNameVo.initQuery(value);
 	if (valNameVo.hasNext())
 	{
 	throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT,
 	getEntityDef().getFullName(), // EO name
 	getPrimaryKey(), // EO PK
 	"Name", // Attribute Name
 	value, // Attribute value
 	"ICX", // Message application short name
 	"FWK_TBX_T_SUP_DUP_NAME"); // Message name
 	}
 	}
 
 	setAttributeInternal(NAME, value);
} // end setName()

4.3 关联迭代

5.实体状态

三、更新/校验

1.属性级校验 2.跨属性校验 3.实体校验 4.跨实体校验 5.不合适的校验失败处理

四、删除

1.校验和级联删除

五、锁

1.过期数据探测

六、提交

七、回滚

1.回滚的方法 2.不合适的Post处理

八、事务取消

标签:OAF,java,name,对象,create,实体,校验,value,服务端
From: https://blog.51cto.com/baiblog/6708963

相关文章

  • 解决生产环境调试 java的具体操作步骤
    生产环境调试Java在开发Java应用程序时,我们通常需要在生产环境中进行调试以解决问题和优化性能。本文将介绍如何在生产环境中进行Java调试的流程和步骤,并提供相应的代码示例。流程概述下表展示了生产环境调试Java的步骤及相应的操作。步骤操作1在项目中添加调试标志......
  • 【Java 新的选择】,Solon v2.3.8 发布
    Solon是什么开源项目?一个,Java新的生态型应用开发框架。它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态规模)。与其他框架相比,它解决了两个重要的痛点:启动慢,费内存。解决痛点?由于SolonBean容器的独特设计,不会因为扩展依赖变多而启动很慢(开发调试时,......
  • 解决正则匹配 在线 JAVA的具体操作步骤
    正则匹配在线JAVA简介正则表达式是一种用于匹配和操作字符串的强大工具。在JAVA中,我们可以使用正则表达式来进行字符串的模式匹配、查找和替换等操作。本文将介绍如何使用JAVA的正则表达式库来进行在线JAVA代码的匹配。正则表达式的基本语法正则表达式由普通字符和特殊字符组成......
  • 解决找不到或无法加载主类java的具体操作步骤
    找不到或无法加载主类JavaJava是一种广泛应用的编程语言,但是在开发和运行Java程序的过程中,有时可能会遇到"找不到或无法加载主类Java"的错误。这个错误表示虚拟机(JVM)无法找到指定的主类来执行程序。本文将探讨该错误的原因和解决方法,并提供一些代码示例来演示。错误原因......
  • 怎么让java从键盘随机输入 来解决一个具体问题的方案
    怎么让Java从键盘随机输入在Java中,我们可以使用Scanner类从键盘获取用户的输入。通过使用Scanner类,我们可以实现从键盘随机输入不同类型的数据,例如整数、浮点数、字符串等。以下是一个示例代码,展示了如何在Java中使用Scanner类从键盘随机输入整数、浮点数和字符串:importjava.ut......
  • 怎么解决java Base64 decode windows和linux不一样 这个问题怎么解决?
    解决JavaBase64解码在Windows和Linux上不一致的问题在Java中,使用Base64进行编码和解码是一种常见的操作。然而,有时候会遇到一个问题,就是在Windows和Linux上进行Base64解码时,结果可能会不一致。这个问题一般是由于操作系统之间的换行符差异引起的。问题描述当我们在Windows上进......
  • 怎么将JAVA代码中的逗号删除 来解决一个具体问题的方案
    怎么将JAVA代码中的逗号删除在Java编程中,有时候我们需要从字符串中删除逗号。这个问题通常出现在处理数字字符串时,例如从CSV文件中读取数据时。本文将介绍一种解决方案来删除Java代码中的逗号。方案我们可以使用Java的字符串处理方法来删除字符串中的逗号。下面是一种方法的示例......
  • 怎么查看java虚拟机的ip地址 来解决一个具体问题的方案
    如何查看Java虚拟机的IP地址在Java开发中,有时我们需要获取本地机器的IP地址,以便与其他机器进行网络通信。这个问题在实际开发中非常常见。本文将介绍如何使用Java代码来查看Java虚拟机的IP地址,并提供示例代码来解决这个问题。1.获取本地机器的IP地址要查看Java虚拟机的IP地址,我......
  • 怎么查看java安装路径 这个问题怎么解决?
    如何查看Java安装路径在开发Java应用程序时,我们经常需要查看Java的安装路径,以便配置环境变量、设置Java路径等操作。本文将介绍几种查看Java安装路径的方法,并提供相应的代码示例。方法一:使用Java命令Java提供了命令行工具java和javac,我们可以通过执行java-version命令来查看Jav......
  • java+geotools实现河流分段+垂线段
    利用动态分段技术进行河流一维水质扩散模拟geotoolssplitlinebyadistance:https://stackoverflow.com/questions/33549915/how-to-split-linestring-into-parts-every-x-meters-with-java-jts(HowtosplitlinestringintopartseveryxmeterswithjavaJTS)https://gi......