我们在Webshop实施中实现了几个自定义ORM对象,这些对象具有对Intershop Product系统对象的引用(依赖性)。
当用户尝试在后台删除某个产品时,这会引起问题,因为在我们的自定义对象中可能仍然存在对该产品的引用。自然地,删除从我们的自定义对象之一引用的产品会产生如下异常:
java.sql.SQLTransactionRollbackException: ORA-02091: transaction rolled back ORA-02292: integrity constraint (INTERSHOP.A1POSTPAIDPRICE_CO_002) violated - child record found
我们认为,可以通过实现ORMObjectListener并重写objectDeleting方法来删除所有引用,然后再实际删除产品来解决此问题。
关于ORM层状态的Intershop食谱:
“实例必须为给定的ORM对象类型实现接口ORMObjectListener并在工厂注册。在创建,更改或删除给定类型的实例时,将调用侦听器。”
但是,我们在工厂找不到用于注册收听者的食谱。我们需要做些什么来注册侦听器?
此外,如果在删除事件期间有一些更好的方法来处理对自定义对象上系统对象的依赖关系,我欢迎您提出建议。
更新:
这是我到目前为止尝试过的侦听器类:
public class ProductDeleteListener implements ORMObjectListener<ProductPO> {
@Inject
ProductPOFactory productPOFactory;
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory.getLogger(ProductDeleteListener.class);
public ProductDeleteListener() {
productPOFactory.addObjectListener(this, new AttributeDescription[0]);
}
@Override
public boolean isOldStateNeeded() {
// TODO Auto-generated method stub
return false;
}
@Override
public void objectChanged(ProductPO object, Map<AttributeDescription, Object> previousValues) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("PRODUCT LISTENER TEST - CHANGE");
}
}
@Override
public void objectChanging(ProductPO object, Map<AttributeDescription, Object> previousValues) {
// TODO Auto-generated method stub
}
@Override
public void objectCreated(ProductPO object) {
// TODO Auto-generated method stub
}
@Override
public void objectCreating(ProductPO object) {
// TODO Auto-generated method stub
}
@Override
public void objectDeleted(ORMObjectKey objectKey) {
// TODO Auto-generated method stub
}
@Override
public void objectDeleting(ProductPO object) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("PRODUCT LISTENER TEST - PRE DELETE");
}
}
}
但是它不起作用。当对象更改或删除时,什么都不会记录。
答案 0 :(得分:3)
除了Willem Evertse编写的内容之外,您还需要将注册代码放在通过Intershop Component Framework实例化的类中。
implementation.component:
<components xmlns="http://www.intershop.de/component/2010" scope="global">
<implementation name="ProductDeleteListenerRegistrar"
class="your.fullqualifed.ProductDeleteRegistrar" start="start" stop="stop"></implementation>
instances.component:
<components xmlns="http://www.intershop.de/component/2010"> <instance name="ORMValidator" with="ORMValidator" scope="global"/></components>
您需要编写一个类,例如ProductDeleteRegistrar并提供start方法,您可以在其中添加注册调用,如Willem所述。至于停止方法,您需要安全地注销您的对象侦听器。确保两个方法都声明为同步。
答案 1 :(得分:2)
我认为注册听众是正确的方法。也许只是寻找性能问题。
您是对的,没有示例,但这是一个示例。
获取要从中接收消息的工厂。您的情况是ProductPOFactory
ProductPOFactory productFactory = (ProductPOFactory) NamingMgr.getInstance().lookupFactory(ProductPO.class);
productFactory.addObjectListener(new MyProductChangeListener());
MyProductChangeListener
需要扩展AbstractORMObjectListener<ProductPO>
并实现方法public void objectDeleting(T object)
每次删除产品时,都应调用侦听器,然后可以清理自定义orm对象。您可以以ImageSetDefinitionPOListener
为例看看