如何在DAO中并发使用Spring Validation Annotation(Bean Validation Specification)

How to use Spring Validation Annotation in DAO concurrently(Bean Validation Specification)

我有一个用户实体,它正在使用 Spring 验证注释 [已编辑 - Bean 验证规范],如下所示。

@NotEmpty(message = "{warn.null.user.password}")
private String            password;

当我用于注册操作时,此验证是可以的,但我试图通过称为更新的不同操作使用相同的实体(用户),我想取消 @NotEmpty 注释。我该怎么做?

此致。

I have a User Entity and it's using Spring Validation Annotation as follow.

首先,它不是"Spring Validation Annotation"。这些是来自 Bean Validation Specification(称为 JSR-303 和 JSR-349)的注释。一些非标准注释由验证提供程序(例如,Hibernate Validator)提供。

But I tried to use the same Entity(User) by different Action called Update and I want to void @NotEmpty Annotation

可以通过注解的groups属性来实现。在第一种情况下,您将 运行 所有组,而在另一种情况下,您将只选择其中的一部分。不幸的是,规范(目前)不支持(因为 @Valid 不允许提供 groups)。

这里是 Spring 的非标准注释 @Validated 派上用场的地方:您可以用它指定验证组!

但它仅适用于控制器中的验证模型。在将实体保存到数据库之前,它不能用作验证,因为无法指定组(Default 始终使用组)。

例如,您可以使用这个问题:Hibernate-validator Groups with Spring MVC

您可以从域模型中的用户实体中删除验证并将其移至服务层。这更有意义,因为实体的验证取决于上下文。

在您的示例中,有 2 个用例:

  • 用户应该可以注册

  • 用户应该能够更改他的数据,例如他的密码。

然后可以像下面的代码一样建模。

 public class User {

        private final String email;
        private String password;

        public User(final String email, final String password) {

            this.email = email;
            this.password = password;
        }

        public void changePassword(final String password) {
            this.password = password;
        }

        public String getEmail() {
            return email;
        }

        public String getPassword() {
            return password;
        }

    }

这还有一个好处,就是您的域模型不依赖于外部库。

您可以将验证从域层移动到服务层,其中验证取决于执行的操作。有一个注册命令和一个更新命令。

用户注册时,邮箱和密码不能为空。

public class RegisterUserCommand {

    @NotEmpty(message = "{warn.null.user.email}")
    private String email;
    @NotEmpty(message = "{warn.null.user.password}")
    private String password;
    ...

更新命令只要求邮箱不为空

public class UpdateUserCommand {

    @NotEmpty(message = "{warn.null.user.email}")
    private String email;
    private String password;
    ...

在服务层你可以做类似的事情:

public class UserService {

    private final UserDao userDao;

    public UserService(final UserDao userDao){
        this.userDao = userDao;
    }

    public User register(final RegisterUserCommand command) {
        User user = new User(command.getEmail(), command.getPassword());
        return userDao.save(user);
    }

    public User update(final UpdateUserCommand command) {
        User user = userDao.findUserByEmail(command.getEmail());
        user.changePassword(command.getPassword);
        return user;

    }

}

这当然只是一个例子,因为我不知道你的其余代码是如何实现的。