如何在 OneToMany 和 ManyToMany 映射中强制执行 min/max/exact 大小的关系集合

How to enforce min/max/exact size of relationship collection in OneToMany and ManyToMany mappings

我的工作代码具有这样的 class:

@Entity
class User {
  @ManyToMany
  @JoinTable(...)
  List<RoleA> aRoles;

  @ManyToMany
  @JoinTable(...)
  List<RoleB> bRoles;

  @OneToMany
  @JoinTable(...)
  List<Address> addresses;
}

我知道如何通过 nullable 属性强制执行至少 1 个。 但是,我感兴趣的是是否可以添加 JPA(不是数据库)检查、约束或验证以强制执行 minimum/maximum/exact 个关系中的实体。

例如最多 3 个地址和最多 10 个角色 A 和最少 2 个角色 B.

Bean 验证规范 (JSR-303) 的一部分是 @Size 注释:

Supported types are String, Collection, Map and arrays. Check if the annotated element size is between min and max (inclusive).

您可以验证集合:

@ManyToMany
@Size(max=10)
List<RoleA> aRoles;

@ManyToMany
@Size(min=2)
List<RoleB> bRoles;

@OneToMany
@Size(max=3)
List<Address> addresses;

没试过,本能地我会用业务代码检查一下。

我从@antoine.lange 那里接受了 因为它本质上就是我要找的东西。

class User {
  @ManyToMany
  @Size(min=1, max=1)
  List<RoleA> aRoles;
}

我已经对此进行了测试,它的工作原理与插入时的预期完全一样。但是,对于更新,Hibernate 不会调用 BeanValidationListener 以防您仅更改集合。作为解决方法,您也必须更改一些基本属性。我将在 Hibernate Jira 上跟进:HHH-13898.

此序列不触发验证:

existingUser.getARoles().add(role1);
existingUser.getARoles().add(role2);
userRepository.saveAndFlush(existingUser);

这个确实如此(并抛出 ConstraintViolationException):

user.setName(newName);
existingUser.getARoles().add(role1);
existingUser.getARoles().add(role2);
userRepository.saveAndFlush(existingUser);