我正在做一个使用JavaFX的项目,Hibernate.

我向字符串主键添加了不为空的约束,但它没有执行任何我预期的验证.它仍然接受空字符串作为有效输入.

我try 了"NotEmpty"、"NotBlank"、"Size"、"Pattern",但不起作用.当我将一个空对象传递给@NotNull时,它仍然执行该工作.我对Hibernate和任何与它相关的东西都是新手,所以我想我缺少基本的知识.

我也试图搜索在Hibernate上进行验证,但我找到了关于Spring MVC的解决方案,以及我在上面try 过的一些进行验证的方法.我发现Hibernate Validator包含许多不推荐使用的注释,并且我正在使用Jakarta验证,我不知道它是否与此相关.

更新:在修改约束时,我try 将hibernate.hbmddl.auto设置为create-drop以重新创建表,但不起作用.

这是我的代码.我希望Apartment.id是非空的,因 for each 居民都应该住在公寓里.

Apartment.java

package com.example.demo;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Apartment {
    @Id
    @NotBlank
    private String id;
}

Resident.java

package com.example.demo;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
public class Resident {
    @Id
    @GeneratedValue
    private Integer id;

    private String firstName;

    private String lastName;

    public Resident(String firstName, String lastName, Apartment apartment) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.apartment = apartment;
    }

    @ManyToOne
    @JoinColumn(nullable = false)
    private Apartment apartment;

}

使用两个实体的代码

package com.example.demo;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;

public class ResidentFormController {

    public TextField firstNameTextField;
    public TextField lastNameTextField;
    public TextField apartmentTextField;
    public Button submitButton;

    private ResidentService residentService;
    private ApartmentService apartmentService;

    @FXML
    public void initialize() {
        residentService = new ResidentService(new ResidentRepository());
        apartmentService = new ApartmentService(new ApartmentRepository());
    }

    public void submitButtonOnAction() {
        Apartment apartment = new Apartment(apartmentTextField.getText());
        apartmentService.merge(apartment);
        residentService.persist(new Resident(
                firstNameTextField.getText(),
                lastNameTextField.getText(),
                apartment
        ));
        SceneManager.switchScene(Scene.RESIDENT_LIST.getFileName());
    }
}

I found this question Validation doesn't work on EntityManager.merge()

并将其作为以下代码进行了try ,但仍然不起作用

public void merge(T entity) {
    HibernateUtility.getSessionFactory().inTransaction(session -> {
        session.merge(entity);
        session.flush();
    });
}

以下是GitHub存储库:https://github.com/GiaoLe/demo

如果有任何部分的代码是不切实际的,有一些说明或参考是很好的,因为我找到了这么多关于Hibernate的过时教程.

非常感谢您抽出时间来.

推荐答案

我不使用Hibernate 验证.我更喜欢依赖数据库.请判断如何为您的特定数据库创建列约束.我认为在您的情况下是MySQL.

对于您的代码:

好的,首先想一想为什么要从文本字段中为公寓设置id?我觉得最好是你自己写的.您可以在公寓中添加额外的字段编号或类似的内容.您的用户最好不要编辑您的记录中的ID.

您的数据库是您的数据源,因此它是放置约束的最重要位置.您还可以在数据库中添加公寓编号(新列)不应为空的约束.那么您将不会保存没有ID和编号的行.

在您的代码中,我将首先判断文本字段是否确实有值,然后判断其余的:

public class ResidentFormController {

...............
 
   public void submitButtonOnAction() {

      if (apartmentTextField.getText() == null || apartmentTextField.getText().trim().isEmpty()) {
          Integer apartmentNumber = apartmentTextField.getText()
          // 1. get the apartment from the db based on number
          Query<User> query = session.createQuery("from Apartment a where a.number=:number", Apartment.class);
          query.setParameter("number", apartmentNumber);
          Apartment apartment = query.uniqueResult()

         Apartment savedApartment;
         // 2.  If null save the apartment in DB before using it
          if(apartment == null)
          {
             savedApartment = apartmentService.persist(new Apartment(apartmentNumber));
          }
          else
          {
             savedApartment = apartment;
          }
          // 3. continue with your code
          residentService.persist(new Resident(
               firstNameTextField.getText(),
               lastNameTextField.getText(),
               savedApartment
          ));
          SceneManager.switchScene(Scene.RESIDENT_LIST.getFileName());
          
      }
      else { 
             // return some error message field is empty
      }

   }

}

更新

好的,我查一下这个说明书:https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-gettingstarted-createmodel

根据它,您需要在pom.xml中使用以下依赖项:

<dependency>
    <groupId>org.glassfish.expressly</groupId>
    <artifactId>expressly</artifactId>
    <version>5.0.0</version>
</dependency>

对于CDI来说,也是如此:

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

您能添加它并判断验证是否有效吗?

Java相关问答推荐

更新我们的一个文物后出现了严重的符号引用错误

具有额外列的Hibert多对多关系在添加关系时返回NonUniqueHealthExcellent

当一个链表中间有一个循环时,它的松散部分会发生什么?

Java中不同包中的类之间的配置共享

如何判断一个矩阵是否为有框矩阵?

在Spring Boot中使用哪个Java类来存储创建时间戳?

Docker不支持弹性APM服务器

我的Spring Boot测试显示&IlLegalStateException:无法加载某事的ApplicationContext.

Domino Designer 14中的保存代理添加了重影库

在执行流和相关操作时,使用Java泛型为2个方法执行相同的操作,但对象不同

Java页面筛选器问题

如何在Java中为thunk创建映射器函数

无法播放音频:从资源加载库GStreamer-Lite失败

将双倍转换为百分比

Spring Validator批注不起作用

协同 routine 似乎并不比JVM线程占用更少的资源

设置背景时缺少Android编辑文本下划线

将Optionals/null安全添加到嵌套的flatMap/流

可以';不要在Intellij IDEA中使用最新的Java版本(JDK 21)

关于正则表达式的一个特定问题,该问题与固定宽度负向后看有关