在实体对象 spring/JPA/Java 上进行验证的缺点



据我所知,有一个原则是不创建具有不适当字段值的类实例。 为了解决这个问题,我使用具有所有必要字段的类构造函数。然后我检查参数并在参数错误时抛出异常。

在 JPA 实体类中使用此解决方案是否合适,或者我应该在服务层中检查它?

参数在控制器层上验证,然后使用休眠注释保存。

@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
@Column(name = ColumnNames.NAME, nullable = true)
@Size(min = 2, max = 50, message = "{person.name.size}")
String name;
@Column(name = ColumnNames.DATE_OF_BIRTH, nullable = true)
private LocalDate dateOfBirth;
protected Person(){}
public Person(String name, LocalDate dateOfBirth)  
throws IllegalArgumentException, NullPointerException { 
Objects.requireNonNull(name);
Objects.requireNonNull(dateOfBirth);
Preconditions.checkArgument(name.length() > 1, 
"Name should have length more than 1 character");
this.name = name;
this.dateOfBirth = dateOfBirth;
}
//getters
}

首先,让我们明确一下典型MVC架构中的三个主要组件。

控制器:控制器组件充当输入和业务逻辑之间的网关。在这里,您可以指定要开发的 API 类型,是GET请求还是POST请求?它应该接受什么样的数据?您的 API 应返回什么作为响应。此层还用于验证来自用户的数据,以便我们不会在服务层中完成所有繁重的工作,然后得出结论,我们一开始就没有适当的数据。在我们总结出数据的健全性之后,我们继续进入实际逻辑实现区域服务

服务:服务应为 API 提供业务逻辑,因此作为存储库的抽象,服务应是唯一有权访问存储库的服务。这是完成所有繁重工作的地方,如果认为有必要,我们会解析到存储库层以访问数据库。

存储库:这是最接近数据库的层,它只是为了处理应用程序和数据库之间的所有通信而存在的。

来到您的案例,您想对实体本身进行验证,它有一些缺点。

  • 安全性:如果要对实体本身进行验证,则通常会在控制器级别公开它,这被认为是一个很大的安全问题,因为您通常会公开表结构,从而使应用程序容易受到攻击。
  • 重量级:所有其他应该处理此问题的层将简单地充当传递,这会增加执行所有工作的实体的负载。
  • 维护:根据 API 本身,您可能会遇到不同的规格。然后,您别无选择,只能使用更新的验证重写整个新实体,这会降低您的可重用性。

如果我不清楚,请随时联系

.

最新更新