验证Jpa实体:在服务中或由生命周期监听器

Pio*_*ski 6 java architecture validation design-patterns jpa

问题在于将Jpa实体的业务验证逻辑放在哪里(或换句话说:您更喜欢哪里).

两个想法是:

  1. 在EntityListener中,保存或更新之前将验证实体
  2. 在提供对jpa持久方法的访问的服务中.

两者都有利弊.当使用方法2时,测试更容易,因为您可能只是模拟jpa提供程序并测试验证逻辑.另一方面,使用#NotNull等验证,验证将在同一时刻进行.

我很想知道如何解决项目中的验证问题,哪种方式更好.

谢谢.

Vin*_*lds 4

这是我遵循的一般经验法则:

使用 Bean 验证时,指定不需要依赖于其他 Bean 的规则。当您依赖另一个 bean 时,让您的服务层来处理该依赖关系。

换句话说,如果您在另一个 bean 中引用了一个 bean,请避免放入 @NotNull 约束。您的服务层最适合用于此目的,因为您可以更早地并且在更合乎逻辑的点捕获违规(因为其他业务验证会假设 bean 可用)。

作为一个例子,考虑以下实体(抱歉它无法编译)

@Entity
public class User
{
   @Id
   private int id;
   @NotNull
   private String fullName;
   @NotNull
   private String email;
   private Set<Role> roles; //No bean validation constraints here.
   ...
   public boolean mapRoleToUser(Role role)
   { //Validation is done here. Including checks for a null role.
   }

}

@Entity
public class Role
{
  @Id
  private int id;
  @NotNull
  private String name;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,服务层应该验证用户是否具有附加角色。在预持久或预更新阶段进行验证有点太晚了,特别是当存在一个具有业务逻辑的不同服务层,并且域模型中的其余业务逻辑时(遗憾的是,我还没有看到仅包含域模型中的所有逻辑就足够好的应用程序)。