Annotation Interface ReferencePath


@Retention(RUNTIME) @Target({ANNOTATION_TYPE,METHOD}) @Documented public @interface ReferencePath
Annotates Java methods that should return all objects found at the far end of a ReferencePath.

This annotation can be used as a convenience to let Permazen auto-generate reference path traversal code. A common use case is inverting references, e.g., from a parent back to a child in a one-to-many relationship.

Annotating an abstract method with @ReferencePath("->some->path") is equivalent to providing an implementation that returns all objects reachable via the reference path "->some->path" when starting at the current instance. References can be traversed in either the forward or inverse directions; see ReferencePath for details on reference paths.

For example:

  @PermazenType
  public interface TreeNode extends PermazenObject {

      /**
       * Get the parent of this node, or null if node is a root.
       */
      TreeNode getParent();
      void setParent(TreeNode parent);

      /**
       * Get the children of this node.
       */
      @ReferencePath("<-TreeNode.parent")
      NavigableSet<TreeNode> getChildren();

      /**
       * Get this node's grandparent, if any.
       */
      @ReferencePath("->parent->parent")
      Optional<TreeNode> getGrandparent();
  }
 
In the example above, the generated getChildren() implementation will be functionally equivalent to (and slightly more efficient than) this one:
      /**
       * Get the children of this node.
       */
      NavigableSet<TreeNode> getChildren() {
          final PermazenTransaction jtx = this.getTransaction();
          final ReferencePath path = jtx.getPermazen().parseReferencePath(this.getClass(), "<-TreeNode.parent");
          return jtx.followReferencePath(path, Collections.singleton(this));
      }
  }
 

Method Return Type

The annotated method must be an instance method and return either NavigableSet<T> or Optional<T>, where T is any super-type of the target object type(s) at the end of the reference path.

If the reference path contains only forward traversals of many-to-one relationships (i.e., simple reference fields), then only one object can be returned and the return type must be Optional<T>.

Otherwise, either return type is valid, and you can use Optional<T> if you only care to retrieve at most a single instance.

More examples:

  @PermazenType
  public interface TreeNode extends PermazenObject {

      /**
       * Get the parent of this node, or null if node is a root.
       */
      TreeNode getParent();
      void setParent(TreeNode parent);

      /**
       * Get the children of this node.
       */
      @ReferencePath("<-TreeNode.parent")
      NavigableSet<TreeNode> getChildren();

      /**
       * Get the siblings of this node (including this node).
       */
      @ReferencePath("->parent<-TreeNode.parent")
      NavigableSet<TreeNode> getSiblings();

      /**
       * Get second cousins once removed (and parents), but only the first.
       */
      @ReferencePath("->parent->parent->parent<-TreeNode.parent<-TreeNode.parent")
      Optional<TreeNode> getSecondCousinOnceRemoved();
  }
 

Meta-Annotations

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

  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    The reference path to follow.
  • Element Details

    • value

      String value
      The reference path to follow.

      The starting type for the reference path is the class containing the annotated method.

      Returns:
      the reference path to traverse
      See Also:
      Default:
      ""