【问题标题】:How to validate on some persistence actions, but not others如何验证某些持久性操作,但不验证其他操作
【发布时间】:2015-07-30 17:18:28
【问题描述】:

我有一个要求,即用户可以“保存”foo 而根本不需要验证,但如果他们“提交”,则必须验证对象。我已经用 Parsley.js 在前端构建并工作了这一切,但想添加后端验证。

使用 Spring/Boot 执行此操作的典型方法是什么?我了解基本的 JPA 验证,但我不知道如何有条件地应用它。

我还想提一下,我尝试使用 Foo 的 2 个子类来执行此操作,但我无法管理切换类型,因为这在 Java 中是不可能的,或者因为我不明白如何实例化对象的新版本,并期望它.equals() 旧版本的 Hibernate 持久性。

感谢您的任何见解。

【问题讨论】:

  • 您需要更清楚地了解您的术语,并可能提供一些伪代码来展示您想要的内容。

标签: spring validation jpa spring-boot


【解决方案1】:
  1. 使用 JSR 303 Validation Groups。这为您提供了条件验证。

  2. 在您的处理程序方法中使用 Spring 的 @Validated。这使您可以在控制器中应用不同的验证

  3. 按照我的例子:http://blog.databasepatterns.com/2014/06/draft-entities-hibernate-validator.html

【讨论】:

  • 很好的建议。您能否建议我如何编写单元测试以确保我的控制器拒绝记录?
【解决方案2】:

JPA 不可能进行条件验证。

为什么?因为很多验证只是数据库约束,不被 JPA 验证,而是无条件地被数据库验证。

例如一个

@NotNull
private Integer value;

将创建一个带有NOT NULL 约束的列。

或者一个

@Size(max = 100)
private String value;

将创建一列VARCHAR(100)

正如您可能理解的那样,不可能将值保存到这样的列中,这样会打破大小限制并具有超过 100 个字符。

确实 - 在 Java 中切换对象的类型是不可能的。

例如,您可以将Entity1 转换为Entity2,但这只是编译器的变量。该对象本身是Entity1 - 无论您尝试什么。但是您可以将所有值从Entity1 的实例复制Entity2 的新实例:

Entity1 entity1 = ...
Entity2 entity2 = new Entity2();
entity2.setProperty(entity1.getProperty());
...
entityManager.persist(entity2);
entityManager.delete(entity1);

如果您不喜欢手动复制所有属性,可以使用 BeanUtils.copyProperties from Apache BeanUtils

【讨论】:

  • 您所描述的复制属性是否允许对实体持久性进行足够的 .equals() 比较?也就是说,假设我将 .equals() 方法配对以仅比较 attr 值而不是 Id/timestamp
  • 我忘记了 bean 验证 - 所以我会说 Neil McGuigans 的答案比我的好 - 最好尝试使用那个。
猜你喜欢
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多