APOC trigger: deletedNodes does not return info of the Node (properties, labels) only the id in before phase

I have a APOC trigger that triggers when deleting a node:

call apoc.trigger.add('remove_components', "UNWIND {deletedNodes} as node call removeComponent(node) return true" ,{phase:'before'})

It calls the following prodecure:

    @Procedure(value = "removeComponent")
    @Description("remove component")
    public void removeComponent(@Name("node") Node node) {
        log.info("Procedure removeComponent triggered by deletion of node with id " + node.getId());
        log.info("Extra info of node with id " + node.getId() + ", labels: " + node.getLabels());
    }

The first log entry is written to the neo4j log. The second log entry gives me the error you will find in the log below. It seems to me that I cannot have extra info about the Node (for example the getLabels()). Is this normal for a before trigger? Is there something I'm doing wrong?

2018-09-11 07:22:20.450+0000 INFO Procedure removeComponent triggered by deletion of node with id 114

2018-09-11 07:22:20.451+0000 WARN Error executing trigger remove_components in phase before Failed to invoke procedure `removeComponent`: Caused by: org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException: Unable to load NODE with id 114.

org.neo4j.graphdb.QueryExecutionException: Failed to invoke procedure `removeComponent`: Caused by: org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException: Unable to load NODE with id 114.

at org.neo4j.kernel.impl.query.QueryExecutionKernelException.asUserException(QueryExecutionKernelException.java:35)

at org.neo4j.cypher.internal.javacompat.ExecutionResult.converted(ExecutionResult.java:405)

at org.neo4j.cypher.internal.javacompat.ExecutionResult.next(ExecutionResult.java:240)

at org.neo4j.cypher.internal.javacompat.ExecutionResult.next(ExecutionResult.java:57)

at org.neo4j.helpers.collection.Iterators.count(Iterators.java:384)

at org.neo4j.helpers.collection.Iterators.count(Iterators.java:368)

at apoc.trigger.Trigger$TriggerHandler.lambda$executeTriggers$0(Trigger.java:231)

at java.util.concurrent.ConcurrentHashMap.forEach(ConcurrentHashMap.java:1597)

at apoc.trigger.Trigger$TriggerHandler.executeTriggers(Trigger.java:220)

at apoc.trigger.Trigger$TriggerHandler.beforeCommit(Trigger.java:211)

at org.neo4j.kernel.internal.TransactionEventHandlers.beforeCommit(TransactionEventHandlers.java:124)

at org.neo4j.kernel.internal.TransactionEventHandlers.beforeCommit(TransactionEventHandlers.java:49)

at org.neo4j.kernel.impl.api.TransactionHooks.beforeCommit(TransactionHooks.java:60)

at org.neo4j.kernel.impl.api.KernelTransactionImplementation.commit(KernelTransactionImplementation.java:620)

at org.neo4j.kernel.impl.api.KernelTransactionImplementation.closeTransaction(KernelTransactionImplementation.java:550)

at org.neo4j.internal.kernel.api.Transaction.close(Transaction.java:189)

at org.neo4j.bolt.v1.runtime.TransactionStateMachine$State.closeTransaction(TransactionStateMachine.java:407)

at org.neo4j.bolt.v1.runtime.TransactionStateMachine$State$1.streamResult(TransactionStateMachine.java:292)

at org.neo4j.bolt.v1.runtime.TransactionStateMachine.streamResult(TransactionStateMachine.java:104)

at org.neo4j.bolt.v1.runtime.BoltStateMachine$State$3.pullAll(BoltStateMachine.java:508)

at org.neo4j.bolt.v1.runtime.BoltStateMachine.pullAll(BoltStateMachine.java:267)

at org.neo4j.bolt.v1.messaging.BoltMessageRouter.lambda$onPullAll$6(BoltMessageRouter.java:114)

at org.neo4j.bolt.runtime.MetricsReportingBoltConnection.lambda$enqueue$0(MetricsReportingBoltConnection.java:69)

at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatch(DefaultBoltConnection.java:195)

at org.neo4j.bolt.runtime.MetricsReportingBoltConnection.processNextBatch(MetricsReportingBoltConnection.java:87)

at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatch(DefaultBoltConnection.java:143)

at org.neo4j.bolt.runtime.ExecutorBoltScheduler.executeBatch(ExecutorBoltScheduler.java:170)

at org.neo4j.bolt.runtime.ExecutorBoltScheduler.lambda$scheduleBatchOrHandleError$2(ExecutorBoltScheduler.java:153)

at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:748)

Yes afaik the information is not available on the node itself as it is already "gone"

You might be able to get it from the other transaction data like

  • removed node properties
  • removed labels

Even in that case, I am not able to get the individual node specific properties. For example, if I need the label of the current node in the Iterator, I wouldnt know that. I could get the list of removed labels, properties but what in case I need the properties specific to the node? I need this information to maintain counter of the properties and having label specific to that node and properties deleted for that node is of essence.

1 Like