2

我们已经在我们的 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 并在工厂注册。在创建、更改或删除给定类型的实例时调用侦听器。”

https://support.intershop.com/kb/index.php/Display/2G3270#Cookbook-ORMLayer-Recipe:NotificationofPersistentObjectChanges

但是,我们在工厂找不到用于注册侦听器的食谱。我们需要做什么来注册监听器?

此外,如果在删除事件期间有更好的方法来处理我们自定义对象上的系统对象的依赖关系,我愿意接受建议。

更新:

这是我到目前为止尝试过的监听器类:

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");
    }

  }

}

但它不起作用。当对象更改或被删除时,不会记录任何内容。

4

2 回答 2

3

除了 Willem Evertse 所写的内容之外,您还需要将注册代码放在一个通过 Intershop 组件框架实例化的类中。

实施.组件:

<components xmlns="http://www.intershop.de/component/2010" scope="global">
<implementation name="ProductDeleteListenerRegistrar"
    class="your.fullqualifed.ProductDeleteRegistrar" start="start" stop="stop"></implementation>

实例.组件:

<components xmlns="http://www.intershop.de/component/2010"> <instance name="ORMValidator" with="ORMValidator" scope="global"/></components>

您需要编写一个类,例如 ProductDeleteRegistrar 并提供 start 方法,您可以在其中添加注册调用,如 Willem 所述。至于停止方法,您需要安全地注销您的对象侦听器。确保两个方法都声明为同步的。

于 2018-07-25T13:57:02.147 回答
2

我认为注册聆听将是正确的方法。也许只是注意性能问题。

你是对的,没有这方面的例子,但这里有一个例子。获取您要从中接收消息的工厂。在你的情况下,它是ProductPOFactory

ProductPOFactory productFactory = (ProductPOFactory) NamingMgr.getInstance().lookupFactory(ProductPO.class);
productFactory.addObjectListener(new MyProductChangeListener());

MyProductChangeListener需要扩展AbstractORMObjectListener<ProductPO> 和实现方法public void objectDeleting(T object)

每次删除产品时,都应该调用您的侦听器,然后您可以清理自定义 orm 对象。你可以看看ImageSetDefinitionPOListener作为一个例子

于 2018-07-25T11:19:20.213 回答