Entity Event Listener on Composition relationships

image
Suppose i have an Order and OrderLine entities, with a composition relationship.

I’ve coded the following entity listener:

@EventListener
public void onPosOrderChangedBeforeCommit(final EntityChangedEvent<PosOrder> event) {
    if (event.getType() == EntityChangedEvent.Type.CREATED) {
        Id<PosOrder> posOrderId = event.getEntityId();
        PosOrder posOrder = dataManager.load(posOrderId).one();
        List<OrderLine> orderLineList = posOrder.getOrderLines();
        for (OrderLine orderLine : orderLineList) {
            log.info(orderLine.getQuantity().toPlainString());
            subtractProductStock(orderLine.getProduct().getId(), orderLine.getQuantity());
        }
    }

    if (event.getType() == EntityChangedEvent.Type.DELETED) {
        Id<PosOrder> oldOrderId = event.getEntityId();
        log.info("Old Order Id: {}",event.getEntityId());
        UUID oldOrderUUID = (UUID) oldOrderId.getValue();
        List<OrderLine> orderLineList = dataManager.load(OrderLine.class)
                .query("select e from OrderLine e where e.posOrder.id = :posOrderId")
                .parameter("posOrderId", oldOrderUUID)
                .list();

        for (OrderLine orderLine : orderLineList) {
            log.info(orderLine.getQuantity().toPlainString());
            addProductStock(orderLine.getProduct().getId(), orderLine.getQuantity());
        }
    }
}

In this case, when a PosOrder is deleted entirely from the PosOrder list view, the line:

    List<OrderLine> orderLineList = dataManager.load(OrderLine.class)

is returning an empty list, even though there actually are entites related.

Why is that? How can i achieve my purpose?

Hi

do you have any cascading options in your entities? have you considered to do changes in buisness code instead of using listeners?

Hi Aleksey

Yes, I do have cascading as it is set by default by jmix studio when creating attributes with composition, in this case, in the OrderLine class that is related to PosOrder.

@OnDeleteInverse(DeletePolicy.CASCADE)
@JoinColumn(name = "POS_ORDER_ID", nullable = false)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private PosOrder posOrder;

About your question, yes, I have considered using other way around, but was given it a try since I thought it would be more straightforward using the entity listeners.

Is this then the expected behavior for entity listeners?

have your tried to remove cacading?

Your OrderLines are deleted together with Order because of DeletePolicy.CASCADE on the relationship. Perhaps you need to invoke your business methods in a OrderLine entity listener.