Intro

There are several use-cases for this feature. One of them is DRY for constraints in DTOs.

Usage

Entities for the examples below
@Entity
public class User extends AbstractDomainObject
{
  @NotNull @Column @Size(min = 2, max = 64)
  private String firstName;

  @NotNull @Column @Size(min = 2, max = 64)
  private String lastName;

  @ManyToMany(mappedBy = "users")
  private List<Group> groups = new ArrayList<Group>();
  //...
}

@Entity
public class Group extends AbstractDomainObject
{
    @NotNull @Column @Size(min = 2, max = 14)
    private String name;

    @ManyToMany(cascade = CascadeType.PERSIST)
    private List<User> users = new ArrayList<User>();
  //...
}
Use-Case 1
@ConstraintSource(User.class)
public class UserDTO
{
  private String firstName; //mapped automatically to User#firstName
  private String lastName;  //mapped automatically to User#lastName

  //...
}
Use-Case 2
@ConstraintSource(User.class)
public class UserDTO
{
  @IgnoreConstraintSource
  @Size(min = 2, max = 32)
  private String firstName; //no mapping - constraints of the current property are used

  @TargetProperty("lastName")
  private String surName;  //mapped to User#lastName

  //...
}
Use-Case 3
@ConstraintSource(User.class)
public class UserDTO
{
  //...

  @ConstraintSource(Group.class)
  private String name;  //mapped to Group#name
}
Use-Case 4
@ConstraintSource(User.class)
public class UserDTO
{
  //...

  @ConstraintSource(Group.class)
  @TargetProperty("name")
  private String defaultGroupName;  //mapped to Group#name
}
Use-Case 5
@Entity
public class User extends AbstractDomainObject
{
  @NotNull @Column @Size(min = 2, max = 64)
  private String firstName;

  @LastName @NotNull @Column @Size(min = 2, max = 64)
  private String lastName;
}

@Target({METHOD, FIELD})
@Retention(RUNTIME)
@interface LastName {
}

@ConstraintSource(User.class)
public class UserDTO
{
  //...

  @ConstraintSource(User.class)
  @TargetPropertyId(LastName.class)
  private String surName;  //mapped to User#lastName
}
  • No labels