Trigger

Hi
I am wondering if there is any option in CUBA studio to include a trigger while creating an Entity. If it is not existing, this could be a good feature in future releases. Let me know if there is any work-around ideas you may suggest.

1 Like

Hi!
See https://docs.cuba-platform.com/cuba/6.0/manual/en/html-single/manual.html#entity_listeners. There is a tab in Studio navigation panel called ‘Entity listeners’ to simplify listeners creation.

Sounds Great! CUBA is becoming my favourite Framework!

Hi
Can you tell me how can I get the inserted record in the listener? For example in SQL server, i can get it from inserted, deleted etc.
Can you refer me to an example please?

Open the link I gave you in the first comment. There is a source code of MyEntityListener class there:


@Component("cuba_MyEntityListener")
public class MyEntityListener implements
        BeforeInsertEntityListener<MyEntity>,
        BeforeUpdateEntityListener<MyEntity> {

    @Inject
    protected Persistence persistence;

    @Override
    public void onBeforeInsert(MyEntity entity) {
        EntityManager em = persistence.getEntityManager();
        ...
    }

    @Override
    public void onBeforeUpdate(MyEntity entity) {
        EntityManager em = persistence.getEntityManager();
        ...
    }
}

The “entity” parameter of the onBeforeInsert(…) method is the entity which is being inserted.

Hi
I have created the following listener but it’s not updating the intended table. I see CUBA has automatically registered it with the Entity, is there any other place this listener has to be registered? Let me know the path or give me hints what I am missing.

 
package com.inteacc.gms.listener; 
import com.haulmont.chile.core.datatypes.impl.IntegerDatatype; 
import com.haulmont.cuba.core.EntityManager; 
import com.haulmont.cuba.core.Persistence; 
import com.inteacc.gms.entity.MaterialTransaction; 
import org.springframework.stereotype.Component; 
import com.haulmont.cuba.core.listener.AfterDeleteEntityListener; 
import com.inteacc.gms.entity.InventoryReceiptVendorLines; 
import com.haulmont.cuba.core.listener.AfterInsertEntityListener; 
import com.haulmont.cuba.core.listener.AfterUpdateEntityListener; 
import javax.inject.Inject; 
/** 
 * @author Mortoza 
 */ 
@Component("inteaccgms_InventoryReceiptVendorLinesBean") 
public class InventoryReceiptVendorLinesListener implements AfterDeleteEntityListener<InventoryReceiptVendorLines>, AfterInsertEntityListener<InventoryReceiptVendorLines>, AfterUpdateEntityListener<InventoryReceiptVendorLines> { 
    @Inject 
    protected Persistence persistence; 
    @Override 
    public void onAfterDelete(InventoryReceiptVendorLines entity) { 
    } 
    @Override 
    public void onAfterInsert(InventoryReceiptVendorLines entity) { 
        EntityManager em = persistence.getEntityManager(); 
        MaterialTransaction transaction = new MaterialTransaction(); 
        transaction.setMaterial(entity.getMaterial()); 
        transaction.setQuantity(entity.getQuantity()); 
        em.persist(entity); 
    } 
    @Override 
    public void onAfterUpdate(InventoryReceiptVendorLines entity) { 
    } 
} 



for the following Entity

 

package com.inteacc.gms.entity; 
import javax.persistence.Entity; 
import javax.persistence.Table; 
import java.math.BigDecimal; 
import javax.persistence.Column; 
import javax.persistence.FetchType; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import com.haulmont.cuba.core.entity.StandardEntity; 
import com.haulmont.cuba.core.entity.annotation.Listeners; 
/** 
 * @author Mortoza 
 */ 
@Listeners("inteaccgms_InventoryReceiptVendorLinesBean") 
@Table(name = "INTEACCGMS_INVENTORY_RECEIPT_VENDOR_LINES") 
@Entity(name = "inteaccgms$InventoryReceiptVendorLines") 
public class InventoryReceiptVendorLines extends StandardEntity { 
    private static final long serialVersionUID = -5738866010051476168L; 
    @ManyToOne(fetch = FetchType.LAZY, optional = false) 
    @JoinColumn(name = "MATERIAL_ID") 
    protected Material material; 
    @Column(name = "QUANTITY", nullable = false) 
    protected BigDecimal quantity; 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "INVENTORY_RECEIPT_VENDOR_ID") 
    protected InventoryReceiptVendor inventoryReceiptVendor; 
    public void setInventoryReceiptVendor(InventoryReceiptVendor inventoryReceiptVendor) { 
        this.inventoryReceiptVendor = inventoryReceiptVendor; 
    } 
    public InventoryReceiptVendor getInventoryReceiptVendor() { 
        return inventoryReceiptVendor; 
    } 
    public void setMaterial(Material material) { 
        this.material = material; 
    } 
    public Material getMaterial() { 
        return material; 
    } 
    public void setQuantity(BigDecimal quantity) { 
        this.quantity = quantity; 
    } 
    public BigDecimal getQuantity() { 
        return quantity; 
    } 
} 



The listener is registered correctly. The problem is that AfterInsertEntityListener does not allow modifications of the current persistence context. So you can’t create an entity with EntityManager and persist it. It is described in the documentation. In your case BeforeInsertEntityListener will work. Try it.

Hi
Thanks, tried it. Now getting the following error message while saving, it was only one record. any suggestions?

 
java.lang.OutOfMemoryError: Java heap space 
    at java.util.Arrays.copyOf(Arrays.java:3332) 
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137) 
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121) 
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:421) 
    at java.lang.StringBuilder.append(StringBuilder.java:136) 
    at java.lang.StringBuilder.append(StringBuilder.java:131) 
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.printStackLine(ThrowableProxyConverter.java:228) 
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.subjoinSTEPArray(ThrowableProxyConverter.java:205) 
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:166) 
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173) 
    at c 



Can you please provide a full stacktrace or better your app.log?

here you go…


2016-03-01 00:29:29 ERROR Exception in com.haulmont.cuba.web.toolkit.ui.CubaButton: com.vaadin.server.ServerRpcManager$RpcInvocationException: Unable to invoke method click in com.vaadin.shared.ui.button.ButtonServerRpc
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:160)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:313)
    at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:202)
    at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:95)
    at com.haulmont.cuba.web.sys.CubaVaadinServletService$CubaUidlRequestHandler.lambda$synchronizedHandleRequest$66(CubaVaadinServletService.java:281)
    at com.haulmont.cuba.web.sys.CubaVaadinServletService$CubaUidlRequestHandler$$Lambda$16/9581532.call(Unknown Source)
    at com.haulmont.cuba.web.sys.CubaVaadinServletService.withUserSession(CubaVaadinServletService.java:171)
    at com.haulmont.cuba.web.sys.CubaVaadinServletService$CubaUidlRequestHandler.synchronizedHandleRequest(CubaVaadinServletService.java:281)
    at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408)
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:356)
    at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:226)
    at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:149)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.haulmont.cuba.web.sys.CubaHttpFilter.handleNotFiltered(CubaHttpFilter.java:100)
    at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:87)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.GeneratedMethodAccessor171.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
    ... 39 more
Caused by: com.vaadin.event.ListenerMethod$MethodException: Invocation of method buttonClick in com.haulmont.cuba.web.gui.components.WebButton$1 failed.
    at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:528)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
    at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1003)
    at com.vaadin.ui.Button.fireClick(Button.java:393)
    at com.haulmont.cuba.web.toolkit.ui.CubaButton.fireClick(CubaButton.java:42)
    at com.vaadin.ui.Button$1.click(Button.java:61)
    ... 43 more
Caused by: java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3332)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:622)
    at java.lang.StringBuilder.append(StringBuilder.java:202)
    at ch.qos.logback.classic.spi.ThrowableProxyUtil.indent(ThrowableProxyUtil.java:104)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.subjoinSTEPArray(ThrowableProxyConverter.java:204)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:166)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)
    at ch.qos.logback.classic.pattern.ThrowableProxyConverter.recursiveAppend(ThrowableProxyConverter.java:173)

I need a full app.log file nevertheless. Please zip it and attach to the comment and also show me what does your listener look like now.

Hi
App.log file is attached.
Here is the listener

 
/*
 * Copyright (c) 2016 inteaccgms
 */
package com.inteacc.gms.listener;

import com.haulmont.chile.core.datatypes.impl.IntegerDatatype;
import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.Persistence;
import com.inteacc.gms.entity.MaterialTransaction;
import org.springframework.stereotype.Component;
import com.haulmont.cuba.core.listener.AfterDeleteEntityListener;
import com.inteacc.gms.entity.InventoryReceiptVendorLines;
import com.haulmont.cuba.core.listener.AfterInsertEntityListener;
import com.haulmont.cuba.core.listener.AfterUpdateEntityListener;

import javax.inject.Inject;
import com.haulmont.cuba.core.listener.BeforeDeleteEntityListener;
import com.haulmont.cuba.core.listener.BeforeInsertEntityListener;
import com.haulmont.cuba.core.listener.BeforeUpdateEntityListener;

/**
 * @author Mortoza
 */
@Component("inteaccgms_InventoryReceiptVendorLinesBean")
public class InventoryReceiptVendorLinesListener implements BeforeDeleteEntityListener<InventoryReceiptVendorLines>, BeforeInsertEntityListener<InventoryReceiptVendorLines>, BeforeUpdateEntityListener<InventoryReceiptVendorLines> {

    @Inject
    protected Persistence persistence;

    /*
    @Override
    public void onAfterInsert(InventoryReceiptVendorLines entity) {
        EntityManager em = persistence.getEntityManager();

        MaterialTransaction transaction = new MaterialTransaction();
        //transaction.setDocNumber(entity.getId());
        transaction.setMaterial(entity.getMaterial());
        //transaction.setMoveCode(new IntegerDatatype(200));
        transaction.setQuantity(entity.getQuantity());
        //  transaction.setTranDate(entity.);

        em.persist(entity);
        em.flush();
    }
*/



    @Override
    public void onBeforeDelete(InventoryReceiptVendorLines entity) {

    }


    @Override
    public void onBeforeInsert(InventoryReceiptVendorLines entity) {
     EntityManager em = persistence.getEntityManager();

        MaterialTransaction transaction = new MaterialTransaction();
        //transaction.setDocNumber(entity.getId());
        transaction.setMaterial(entity.getMaterial());
        //transaction.setMoveCode(new IntegerDatatype(200));
        transaction.setQuantity(entity.getQuantity());
        //  transaction.setTranDate(entity.);

        em.persist(entity);
        em.flush();

    }


    @Override
    public void onBeforeUpdate(InventoryReceiptVendorLines entity) {

    }


}

app.log (97.9K)

You don’t need em.flush() line. Remove it.

Hi
I’ve removed the em.flush(). Now no such error but no result. The table updated in the trigger is still empty. Thanks for your further help.

Here is the listener file

 
package com.inteacc.gms.listener; 
import com.haulmont.chile.core.datatypes.impl.IntegerDatatype; 
import com.haulmont.cuba.core.EntityManager; 
import com.haulmont.cuba.core.Persistence; 
import com.inteacc.gms.entity.MaterialTransaction; 
import org.springframework.stereotype.Component; 
import com.haulmont.cuba.core.listener.AfterDeleteEntityListener; 
import com.inteacc.gms.entity.InventoryReceiptVendorLines; 
import com.haulmont.cuba.core.listener.AfterInsertEntityListener; 
import com.haulmont.cuba.core.listener.AfterUpdateEntityListener; 
import javax.inject.Inject; 
import com.haulmont.cuba.core.listener.BeforeDeleteEntityListener; 
import com.haulmont.cuba.core.listener.BeforeInsertEntityListener; 
import com.haulmont.cuba.core.listener.BeforeUpdateEntityListener; 
import com.haulmont.cuba.core.listener.BeforeAttachEntityListener; 
/** 
 * @author Mortoza 
 */ 
@Component("inteaccgms_InventoryReceiptVendorLinesBean") 
public class InventoryReceiptVendorLinesListener implements BeforeDeleteEntityListener<InventoryReceiptVendorLines>, BeforeInsertEntityListener<InventoryReceiptVendorLines>, BeforeUpdateEntityListener<InventoryReceiptVendorLines>, BeforeAttachEntityListener<InventoryReceiptVendorLines> { 
    @Inject 
    protected Persistence persistence; 
    @Override 
    public void onBeforeDelete(InventoryReceiptVendorLines entity) { 
    } 
    @Override 
    public void onBeforeInsert(InventoryReceiptVendorLines entity) { 
     EntityManager em = persistence.getEntityManager(); 
        MaterialTransaction transaction = new MaterialTransaction(); 
        transaction.setMaterial(entity.getMaterial()); 
        transaction.setQuantity(entity.getQuantity()); 
        em.persist(entity); 
    } 
    @Override 
    public void onBeforeUpdate(InventoryReceiptVendorLines entity) { 
    } 
    @Override 
    public void onBeforeAttach(InventoryReceiptVendorLines entity) { 
    } 
} 



Hi
Please make a simple demo project with 2 entities that reproduces your issue and attach it here. I will take a look.