EBS OAF开发中的Java 实体对象(Entity Object)验证功能补充
(版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处;否则请与本人联系,违者必究)
EO理论上是只有产品组维护,里面包含其所有的业务逻辑,并提供相应的Expert给自己或者其它产品组使用。而VO是各个组根据需要或基于EO或者只读的SQL而建立的,里面可以根据需要添加自己的业务实现和逻辑。
对于EO内部的验证功能,在开发文档中主要介绍了三种:
1. 在setter里面实现单个属性的验证。这主要是对于没有依赖关系的属性,也就是说它的验证不需要其它会被修改的属性的支持。比如,验证一个数量是不是正数,是不是在一个范围之内;但是如果其也要依赖界面上的输入的计量单位的话,就要考虑row层次上的验证,因为setter的调用顺序是未知的,可能先调用数量的setter,然后再调用计量单位的setter,这样的验证就会有问题了。
2. 在Row层次上进行跨属性的验证.因为在所有需要调用的setter都调用完之后,会调用row层次的验证方法validateEntity().所有行级的跨属性验证都应该放在这里。它的缺点是,每次request中如果有调用setter的话,就会调用row层次的校验,所以在开发文档中有这么一句话,
Any logic which operates at the row level -- and is not particularly sensitive to being called repeatedly --should be included in the validateEntity() method.
也就是说所有行级的且对重复调用不敏感的验证可以放在这里,如何定义敏感,我的理解是1.每次验证花费的时间很多;2.一个transaction里多次请求每次都会调用setter,比如大量的PPR事件,会导致多次验证,可能影响用户体验;但是开发文档中虽然这么说了,但并没有说明这种不能重复调用的验证应该在哪里实现,如何实现。
3. 进行跨实体属性验证.对于composition的AO来说,这个不是问题,因为detail的验证总是发生在master的验证之前;而对于reference的来说,就要实现类似“调解人”的对象,其需要实现ValidationListener接口。但这种情况较少,而且适用范围较小。
对于第二种情况的例外,可以考虑覆盖基类OAEntityImpl的prepareForDML()方法.对于其,Javadoc有下面的说明
Process a row when any operation like insert/update/deleteis performed. User can overwrite this method and add any custom logic, likeinitialize any attribute on insertion.
也就是在构建DML SQL语句之前,我们可以对这个row做一些处理,比如设置一些属性且其只有在保存的时候才需要设置的,如获取sequence之类的(这个我测试过,确实可以);或者做一些只有保存时才需要的验证(这个没有测试过,理论上应该可以,后面有空的话会测试一下).