首页 > 解决方案 > Hibernate 只执行 java 属性的第一个自定义约束

问题描述

我正在使用 Hibernate 为我的 java 模型创建自定义约束注释。调用每个约束时都会返回特定的 API 错误消息和 400 Bad Request 作为 HTTP 状态代码。每个约束的响应:-

{
"errorMsg": "revoked id",
"errorCode": 400
},

{
"errorMsg": "paused id",
"errorCode": 400
},

{
"errorMsg": "expired id",
"errorCode": 400
}

这些是创建的自定义约束ExistingExpiredId, ExistingPausedId, ExistingRevokedId:-

@NotBlank
@ExistingExpiredId
@ExistingPausedId
@ExistingRevokedId
private String id;

ID 可以有以下状态:- EXPIRED, PAUSED, REVOKED。目前我有自定义注释来检查属性的不同状态。每个自定义约束都会对数据库进行存储库调用以选择属性所处的特定状态。我看到所有约束都被调用,因此对数据库进行了 3 次调用,这对于单个属性来说非常昂贵。如何确保一次只调用三个约束中的一个而不是全部三个?是否hibernate提供任何机制来实现这一点?

标签: javaspring-boothibernaterepositoryconstraints

解决方案


@GroupSequence是排序验证约束的标准方式。唯一需要注意的是,您需要将每个约束放在一个单独的组中。

如果我是你,我会创建一个参数化的约束注解(带有一个Status[] value()属性),用给定的idstates 检查对象是否存在,然后你可以按如下方式使用它:

@ExistingId(State.EXPIRED) // check if an expired entity exists

@ExistingId(State.PAUSED) // check if a paused entity exists

@ExistingId({State.EXPIRED, State.PAUSED, State.REVOKED}) // check if an entity exists in any of the listed statuses

如果你愿意,你可以给一些状态配置的版本起别名,如下所示:

@Constraint(validatedBy = {})
@Target(...)
@Retention(RUNTIME)
@ExistingId(Status.EXPIRED)
public @interface ExistingExpiredId {...}

推荐阅读