Hibernate仅执行Java属性的第一个自定义约束

问题描述

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

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

这些是创建的自定义约束ExistingExpiredIdExistingPausedIdExistingRevokedId:-

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

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

解决方法

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

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

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