【问题标题】:Drawbacks on having validations on Entity object spring/JPA/Java对实体对象 spring/JPA/Java 进行验证的缺点
【发布时间】:2019-12-03 12:26:23
【问题描述】:

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

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

在使用 Hibernate 注释保存之前,在控制器层验证参数。

@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
}

【问题讨论】:

  • 始终建议在控制器端处理数据验证。典型的企业系统会在控制器层进行数据验证,在服务层进行业务逻辑和实现,在存储层进行实际更改
  • @Coder 非常感谢您的回答!由于 Hibernate 注释,我在控制器层和保存之前验证数据。使用实体构造函数验证是一种不好的做法吗?我想它可以防止“错误”的类实例。
  • 你得到你想要的东西了吗?或者你有任何后续问题?

标签: java jpa orm entity


【解决方案1】:

首先让我们弄清楚典型MVC 架构中的三个主要组件。

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

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

Repository:这是最接近数据库的层,它只是用来处理应用程序和数据库之间的所有通信。

谈到你的情况,你想对实体本身进行验证,它有一些缺点。

  • 安全性:如果您对实体本身进行验证,则通常会将其暴露在控制器级别,这被认为是一个重大的安全问题,因为您通常会暴露表结构,从而使应用程序易受攻击。
  • 重量级:本应处理此问题的所有其他层将仅充当通道,这会增加执行所有工作的实体的负载。
  • 维护:您可能会遇到不同的规范,具体取决于 API 本身。然后,您别无选择,只能使用更新的验证重写一个全新的实体,这会降低您的可重用性。

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

.

【讨论】:

    猜你喜欢
    • 2013-10-25
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 2011-04-30
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多