Annotation Interface OnDelete


Annotates Permazen model class methods that are to be invoked whenever an object is about to be deleted.

Overview

When a matching object is deleted, annotated methods are invoked just prior to actual deletion.

For instance methods, a matching object is one that is found at the end of the reference path specified by path(), starting from the object to be notified, and whose type is compatible with the method's only parameter. By default, path() is empty, which means deletion of the object itself is monitored. See ReferencePath for more information about reference paths.

For static methods, path() must be empty and every object is a potential matching object. Therefore, the deletion of any object whose type is compatible with the method's parameter will result in a notification.

The annotated method may may have any level of access, including private. It must return void and take one parameter representing the deleted object; however, an instance method with an empty path() may take zero parameters, as the deleted object is always the same as the notified object.

A class may have multiple @OnDelete methods, each with a specific purpose.

Examples

This example shows various ways an annotated method can be matched:


   @PermazenType
   public abstract class User implements PermazenObject {

       public abstract Account getAccount();
       public abstract void setAccount(Account account);

       @OnDelete(path = "->account")
       private void handleDeletion1(Account account) {
           // Invoked when MY Account is deleted
       }
   }

   @PermazenType
   public abstract class Feature implements PermazenObject {

       public abstract Account getAccount();
       public abstract void setAccount(Account account);

       @OnDelete(path = "->account<-User.account")
       private void handleDeletion1(User user) {
           // Invoked when ANY User associated with MY Account is deleted
       }
   }

   @PermazenType
   public abstract class Account implements PermazenObject {

       @NotNull
       public abstract String getName();
       public abstract void setName(String name);

   // Non-static @OnDelete methods

       @OnDelete
       private void handleDeletion1() {
           // Invoked when THIS Account is deleted
       }

       @OnDelete
       private void handleDeletion2(SpecialAccount self) {
           // Invoked when THIS Account is deleted IF it's also a SpecialAccount
       }

       @OnDelete(path = "<-User.account")
       private void handleDeletion3(User user) {
           // Invoked when ANY User associated with THIS Account is deleted
       }

       @OnDelete(path = "<-User.account")
       private void handleDeletion4(Object obj) {
           // Invoked when ANY User OR Feature associated with THIS Account is deleted
       }

       @OnDelete(path = "<-Feature.account->account<-User.account")
       private void handleDeletion5(User user) {
           // Invoked when ANY User associated with the same Account
           // as ANY Feature associated with THIS Account is deleted
       }

  // Static @OnDelete methods

       @OnDelete
       private static void handleDeletion5(Object obj) {
           // Invoked when ANY object is deleted
       }

       @OnDelete
       private static void handleDeletion6(Account account) {
           // Invoked when ANY Account is deleted
       }
   }
 

Instance vs. Static Methods

An instance method will be invoked on each object for which the deleted object is found at the end of the specified reference path, starting from that object. For example, if there are three child Node's pointing to the same parent Node, and the Node class has an instance method annotated with @OnDelete(path = "parent"), then all three child Node's will be notified when the parent is deleted.

A static method is invoked once for any matching object; the path() is ignored and must be empty.

Notification Delivery

Notifications are delivered in the same thread that deletes the object, before the deletion actually occurs. At most one delete notification will ever be delivered for any object deletion event. In particular, if an annotated method attempts to re-entrantly delete the same object again, no new notification is delivered.

Some notifications may need to be ignored by objects in detached transactions; you can use this.isDetached() to detect that situation.

Actions that have effects visible to the outside world should be made contingent on successful transaction commit, for example, via Transaction.addCallback().

Meta-Annotations

This annotation may be configured indirectly as a Spring meta-annotation when spring-core is on the classpath.

See Also:
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Specify the reference path to the target object(s) that should be monitored for deletion.
  • Element Details

    • path

      String path
      Specify the reference path to the target object(s) that should be monitored for deletion. See ReferencePath for information on reference paths and their proper syntax.

      The default empty path means the monitored object and the notified object are the same.

      When annotating static methods, this property is unused and must be left unset.

      Returns:
      reference path leading to monitored objects
      See Also:
      Default:
      ""