当前位置: 首页 > 知识库问答 >
问题:

注释引用的约束验证符永远不会被调用,尽管它应该工作

阴迪
2023-03-14

调试器中,我可以看到注释以某种方式工作。但是类AuthorConstraintValidator的方法初始化(AuthorConstraint)isValid(作者,ConstraintValidatorContext)从未被调用。

我花了好几个小时寻找解决方案。但我不知道缺少了什么。

包:hibernate-core 5 . 6 . 5 . final hibernate-validator 6 . 2 . 3 . final

package myapp.entity.author.constraint;

import javax.validation.Constraint;
import javax.validation.Payload;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * An annotation for special constraints of authors.
 */
@Constraint(validatedBy = {AuthorConstraintValidator.class})
@Retention(RUNTIME)
@Target({TYPE})
public @interface AuthorConstraint {
    String message() default "An author needs either a first name or a last name.";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
package myapp.entity.author.constraint;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import myapp.entity.author.Author;

/**
 * A validator for special constraints of authors.
 */
public class AuthorConstraintValidator implements ConstraintValidator<AuthorConstraint, Author> {
    /**
     * {@inheritDoc}
     */
    @Override
    public void initialize(AuthorConstraint constraintAnnotation) {
    }

    @Override
    public boolean isValid(Author author, ConstraintValidatorContext constraintValidatorContext) {
        if (author == null) {
            return true;
        }

        return author.getFirstName() != null || author.getLastName() != null;
    }
}
package myapp.entity.author;

import myapp.data.DatedEntity;
import myapp.entity.author.constraint.AuthorConstraint;

import javax.persistence.*;
import java.io.Serializable;

/**
 * Represents an author.
 */
@AuthorConstraint
@Entity
@Table(name = "author")
public class Author extends DatedEntity implements Serializable {
    /**
     * ID associated with an author.
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    /**
     * First name of an author.
     */
    @Column(name = "first_name")
    private String firstName;

    /**
     * Last name of an author.
     */
    @Column(name = "last_name")
    private String lastName;

    /**
     * Returns the ID associated with an author.
     *
     * @return Primary key of an author.
     */
    public Integer getId() {
        return id;
    }

    /**
     * Sets the ID of an author.
     *
     * @param id the ID of an author
     */
    @SuppressWarnings({"unused", "SameParameterValue"})
    void setId(Integer id) {
        this.id = id;
    }

    /**
     * Returns the first name of an author.
     *
     * @return First name of an author.
     */
    @SuppressWarnings("unused")
    public String getFirstName() {
        return firstName;
    }

    /**
     * Sets the first name of an author.
     *
     * @param firstName first name
     */
    @SuppressWarnings("unused")
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * Returns the last name of an author.
     *
     * @return Last name of an author.
     */
    @SuppressWarnings("unused")
    public String getLastName() {
        return lastName;
    }

    /**
     * Sets the last name of an author.
     *
     * @param lastName last name
     */
    @SuppressWarnings("unused")
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

当我自己创建验证器对象时,我可以看到它按预期工作。

Author author = new Author();
AuthorConstraintValidator validator = new AuthorConstraintValidator();

validator.initialize(new AuthorConstraint() {
    @Override
    public Class<? extends Annotation> annotationType() {
        return AuthorConstraint.class;
    }

    @Override
    public String message() {
        return null;
    }

    @Override
    public Class<?>[] groups() {
        return new Class[0];
    }

    @Override
    public Class<? extends Payload>[] payload() {
        return new Class[0];
    }
});

System.err.println(validator.isValid(author, null));
// result: false

共有1个答案

何长恨
2023-03-14

您正在将支持 javax.* 注释的组件与支持雅加达注释的组件混合在一起。

如果您使用的是< code>javax.persistence,您应该使用< code>javax.validation,从而使用Hibernate Validator 6.2.x。它仍然受支持,并具有与HV 7.0.x(针对Jakarta EE 9,因此是< code>jakarta.validation包)和即将发布的HV 8.0.x(针对Jakarta EE 10)相同的功能。

所以改用Hibernate Validator 6.2和Bean Validation 2.0。

您还应该检查您的EL实现版本。应该是:

  <dependency>
     <groupId>org.glassfish</groupId>
     <artifactId>jakarta.el</artifactId>
     <version>3.0.3</version>
  </dependency>

确保你身边没有另一个,因为它们有一大堆不同的名字。

然后,如果它仍然不起作用,一件事是默认情况下,Hibernate ORM在尝试初始化Hibernate Validator时不会告诉您是否出了问题。

您可以通过将以下属性设置为CALLBACK来让它告诉您发生了什么:

  • javax.persistence.validation.group.pre-坚持
  • javax.persistence.validation.group.pre更新
  • javax.persistence.validation.group.pre-删除
 类似资料:
  • 问题内容: 看过很多论坛,但没有找到答案…简单的东西,用@PostLoad注释的方法永远不会被调用…通过@EntityListeners添加了侦听器,但问题仍然存在。我正在使用基于SessionFactory的配置。 问题答案: 当使用基于基础的配置时,EJB3 注释不起作用,后期加载方法将永远不会被调用。 使用Hibernate的Interceptor或事件或基于基本的配置。

  • (仅在测试中使用)我有依赖项(没有spring或DI容器) 我可以通过 myDto在哪里 哪里 哪里 在这个验证器中,所有的工作都很完美,但没有任何注释或在现场发挥作用,他们只是被忽略了 请帮忙。断然的 很抱歉,我的真实案例是相互嵌套的DTO,所以只有高级类经过验证,但没有嵌套。 而另一个有注释的字段未经验证。当我在字段中添加时,它开始正常工作

  • 我们正在开发REST服务,并希望使用JSR303进行输入数据验证,但这里的问题是所有模型对象都是从groovy DSL生成的,并将作为jars导入。因此,在对象字段之上编写JSR-303注释没有灵活性。 那么,有没有其他方法可以不用注释使用JSR-303,可以通过XML配置吗?或者在这种情况下,请提供任何验证建议。 谢啦

  • 我有一个用Java验证注释注释的模型对象。 根据业务需求,将填充文件名或小时字段,以验证我编写的自定义验证器“CriteriaValidator”。 上面的模型作为方法的输入参数传入,该方法也用@Valid和@ValidCriteria注释。 我的问题是方法中的2个注释。我必须添加@Valid才能检查类中注释的约束。我的自定义验证器仅检查两个字段之一的存在:文件名或小时。 我的问题是,如何使用单个

  • 我想知道是否有可能将一些自定义类型的新约束验证器注册到Bean验证规范定义的注释中。例如,让我们想象一下,我有一个类,它累加了几个int值 我想注册一个自定义约束验证器来支持这种类型的@正向注释(而不是创建自定义注释)。 这样以后我就可以使用这个:

  • 我在测试一些短信发送和接收结果应用程序。它按预期发送短信,并祝酒“短信发送”。但它从不祝酒“短信发送”。它也从来没有达到 这意味着从不需要为结果SMS_DELIVERED...知道为什么吗?... Androidanifest.xml