【问题标题】:Validation of a date with Hibernate使用 Hibernate 验证日期
【发布时间】:2017-03-21 19:18:13
【问题描述】:

我们有一个现有的酒店管理系统。我被要求在系统的“创建住宿”功能中添加日期验证。对话框如下所示:

“结束日期”已经过验证,如下面的代码所示。 Hibernate 中的@Future 注解确保日期在未来。

@NotNull
@Future
@DateTimeFormat(pattern = "dd/MM/yyyy")
@Temporal(TemporalType.DATE)
private Date endDate;

编辑

我被要求为“开始日期”添加验证。只允许现在或将来的日期。我尝试使用@Present 注释,但我想没有这样的东西。不幸的是,@Future 不接受今天的日期。我对这种事情很陌生。所以我希望有人能帮助我。谢谢。

【问题讨论】:

  • 注解@Future来自什么类/框架?
  • 我认为它是休眠的
  • 如果当前日期是唯一有效的值,为什么还要有这个字段?
  • 请注意,您的表单格式 (mm/dd/yyyy) 和注释格式 (dd/MM/yyyy) 不匹配。
  • @Axel 导入 javax.validation.constraints.Future;

标签: java hibernate validation date annotations


【解决方案1】:

现在,在更新的新验证器版本中,即

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.4.Final</version>
</dependency>

通过

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.0.Final</version>
</dependency>

我们有 @FutureOrPresent 和许多其他有用的注释供您使用。

【讨论】:

    【解决方案2】:

    休眠

    你可以使用

    @CreationTimestamp
    @Temporal(TemporalType.DATE)
    @Column(name = "create_date")
    private Date startDate;
    

    或更新中

    @UpdateTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "modify_date")
    private Date startDate;
    

    Java (JPA)

    你可以定义一个字段Date startDate;并使用

    @PrePersist
    protected void onCreateStartDate() {
    startDate = new Date();
    

    或更新中

    @PreUpdate
    protected void onUpdateStartDate() {
    startDate = new Date();
    

    更新和示例

    在您更新问题以不将开始日期固定到现在之后,您必须采取不同的方法。您需要编写一个自定义验证器来检查日期是现在还是将来,例如 here

    因此你可以在PresentOrFuture.java中引入一个新的注解:

    @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = PresentOrFutureValidator.class)
    @Documented
    public @interface PresentOrFuture {
        String message() default "{PresentOrFuture.message}";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
    

    那么你必须在PresentOrFutureValidator.java中定义验证器:

    public class PresentOrFutureValidator
        implements ConstraintValidator<PresentOrFuture, Date> {
    
        public final void initialize(final PresentOrFuture annotation) {}
    
        public final boolean isValid(final Date value,
            final ConstraintValidatorContext context) {
    
            // Only use the date for comparison
            Calendar calendar = Calendar.getInstance(); 
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
    
            Date today = calendar.getTime();
    
            // Your date must be after today or today (== not before today)
            return !value.before(today) || value.after(today);
    
        }
    }
    

    然后你必须设置:

    @NotNull
    @PresentOrFuture
    @DateTimeFormat(pattern = "dd/MM/yyyy")
    @Temporal(TemporalType.DATE)
    private Date startDate;
    

    嗯,那是详尽无遗的。我自己没有测试过,因为我现在没有设置可以这样做,但它应该可以工作。希望对你有帮助。

    【讨论】:

    • 抱歉先生回复晚了。这是startDate的代码:pastie.org/10958151希望你能指导我。谢谢。
    • 如果只能允许当前时间戳,为什么还要有setter方法呢?你使用 Hibernate 还是 JPA?
    • 抱歉,先生,我编辑了我的问题。它应该接受当前和未来的日期。我使用休眠。
    • 感谢您的帮助,先生! :) 我会试试这个并更新你。 :)
    • 我试过你的代码先生。我创建了一个PresentOrFuture.java 注释和PresentOrFutureValidator.java 类并添加了@PresentOrFuture 但每当我尝试运行该程序时,我都会收到此错误:“Web 应用程序 [/hms] 注册了 JDBC 驱动程序 [org.hsqldb.jdbc.JDBCDriver ] 但在 web 应用程序停止时未能取消注册。为防止内存泄漏,已强制取消注册 JDBC 驱动程序。"
    【解决方案3】:

    最简单的方法是不禁用该字段(不可编辑)并填充当前日期。所以您不需要验证。

    如果您不喜欢这种方法,请创建自己的注释,请参考此网址
    Annotation for hibernate validator for a date at least 24 hours in the future

    您需要检查日期值是否等于当前日期,而不是 24 小时检查

    【讨论】:

      猜你喜欢
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-24
      相关资源
      最近更新 更多