Annotation Interface ProjectionPostConvert


@Target(METHOD) @Retention(RUNTIME) @Documented public @interface ProjectionPostConvert
Perform a post conversion mapping operation during the auto projection flow for a repository entity member of a related OneToMany collection. This is useful, for example, to map bidirectional references back to a parent entity for OneToMany collections. This annotation is useful in flows where ModelMapperMappable has not be implemented for the extension or new domain (i.e. no toMe/fromMe implementations). The annotation provides the hook point to perform the additional, interesting mapping in the deep nested entity. However, if ModelMapperMappable is implemented, this annotation can still be used in the deep nested entity as a convenience, or the interesting mapping code can be handled explicitly in the toMe implementation on the top-level entity.

This is a marker annotation. It should accompany a public void method that accepts a source parameter for the original projection, and a parent parameter that is the backreference to the entity containing the collection. The implementation should use the parent parameter as appropriate to set any parent references in the current entity to fulfill bi-directional reference requirements for the ORM. The system will support arbitrary deep nesting of collection associations originating from a root repository domain class that participates in auto mapping (i.e. does not use ModelMapperMappable). Other mapping activities may be performed as well by harvesting information from the projection or parent method parameters.

Example:
 @Entity
 @Table(name = "MY_PARENT")
 @Inheritance(strategy = InheritanceType.JOINED)
 @Data
 @EqualsAndHashCode(exclude = {"_id", "myParent"})
 public class MyDomain {

      @Id
      @GeneratedValue(generator = "blcid")
      @GenericGenerator(name = "blcid", strategy = "blcid")
      @Type(UlidUserType.class)
      @Column(name = "ID", nullable = false, length = CONTEXT_ID_LENGTH)
      @ExplicitProjectionFieldConfiguration(ignore = true) // Don't include in projection
      private String _id;

      @ManyToOne(cascade = CascadeType.REFRESH)
      @JoinColumn(name = "MY_PARENT_ID")
      @ToString.Exclude // Avoid infinite recursion in toString()
      @JsonIgnore // Avoid infinite recursion in data tracking
      @ExplicitProjectionFieldConfiguration(ignore = true) // Don't include in projection
      private MyParent myParent;

      @ProjectionPostConvert
      public void postConvert(Object source, Object parent) {
          Assert.isTrue(ref instanceof MyParent, "Expected an instance of MyParent");
          setMyParent((MyParent) parent);
      }

      ...
 }
 
See Also:
  • ProjectionFactory