【问题标题】:@NotNull annotation does not translate to not null constraint in schema generation@NotNull 注释在模式生成中不会转换为非空约束
【发布时间】:2018-12-17 21:03:00
【问题描述】:

根据休眠验证器参考文档 - 第 11.1.1 节。数据库架构级验证 (https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-checkconstraints-db),

开箱即用,Hibernate ORM 将转换您拥有的约束 为您的实体定义到映射元数据。例如,如果一个 您的实体的属性被注释为@NotNull,它的列将是 在 Hibernate ORM 生成的 DDL 模式中声明为 not null。

但是当我用 @NotNull 注释我的字段时,我没有自动获得架构级别的约束。

我尝试将Environment.HBM2DDL_AUTO 设置为update 和create,但都无法生成数据库约束。

尽管默认情况下休眠将hibernate.validator.apply_to_ddl 设置为true,但我什至尝试手动设置 -

settings.put("hibernate.validator.apply_to_ddl", true);

但这些选项似乎都不适合我。

我的域类

package com.praveen.domain;

import javax.persistence.Entity;
import javax.validation.constraints.NotNull;

import lombok.Data;

@Entity
@Data
public class Stakeholder extends MyPersistent {

    @NotNull
    private String clientCode;

    @NotNull
    private String gender;
}

MyPersistent 类

package com.praveen.domain;

import java.io.Serializable;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

import lombok.Getter;
import lombok.Setter;

@MappedSuperclass
@Getter
@Setter
public class MyPersistent implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

我用来获取会话工厂的代码是

    private static SessionFactory getSessionFactory() {
        if (sessionFactory == null) {
            try {
                StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder();

                Map<String, Object> settings = new HashMap<>();
                settings.put(Environment.DRIVER, Driver.class.getName());
                settings.put(Environment.URL, "jdbc:mysql://localhost:3306/hibernate_test?"
                        + "zeroDateTimeBehavior=CONVERT_TO_NULL&"
                        + "createDatabaseIfNotExist=true&"
                        + "useSSL=true&"
                        + "verifyServerCertificate=false&"
                        + "autoReconnect=true");
                settings.put(Environment.USER, "root");
                settings.put(Environment.PASS, "");
                settings.put(Environment.DIALECT, MySQL55Dialect.class);
                settings.put(Environment.HBM2DDL_AUTO, "update");
                settings.put(Environment.SHOW_SQL, false);

                // HikariCP settings
                settings.put("hibernate.hikari.connectionTimeout", "20000");
                settings.put("hibernate.hikari.minimumIdle", "5");
                settings.put("hibernate.hikari.maximumPoolSize", "20");
                settings.put("hibernate.hikari.idleTimeout", "300000");

                registryBuilder.applySettings(settings);
                registry = registryBuilder.build();
                MetadataSources sources = new MetadataSources(registry);
                sources.addAnnotatedClass(Stakeholder.class);

                Metadata metadata = sources.getMetadataBuilder().build();
                sessionFactory = metadata.getSessionFactoryBuilder().build();
            } catch (Exception e) {
                e.printStackTrace();
                shutdown();
            }
        }
        return sessionFactory;
    }

【问题讨论】:

  • @Kayaman,我在发布我自己的帖子之前参考了该帖子,它明确指出“由于 Hibernate 是 JSR 303 的参考实现,但是它智能地获取这些约束并将它们转换为数据库限制你,所以你以一个的价格得到两个”。但由于某种原因,它对我没有用,我在问为什么。
  • 明确地说,这是您从空白数据库创建新架构的情况,还是您试图让 Hibernate 将约束应用于现有架构?
  • 我尝试了两种情况,但结果是一样的

标签: java hibernate hibernate-validator hibernate-5.x mysql-5.5


【解决方案1】:

你应该使用 @Column(nullable = false)

@NotNull 用于 Bean 验证,而不是模式约束,如果您使用的是旧版本的 hibernate,@NotNull 将不会被转换为列约束

【讨论】:

  • 我正在使用最新的稳定版本:- hibernate-core - 5.3.1 hibernate-validator - 6.0.10 javax.persistence-api - 2.2 validation-api-2.0.1
  • 或许还是值得尝试缩小问题范围
【解决方案2】:

这是一个愚蠢的错误,因为我没有在 pom.xml 中包含 javax.el 依赖项及其实现。

有趣的是,那时我还没有收到java.lang.NoClassDefFoundError: javax/el/ELManager 错误,因为我还没有编写任何代码来通过Validation.buildDefaultValidatorFactory() 初始化ValidatorFactory。

当我编写代码并使用 ValidatorFactory 后,我得到了 NoClassDefFoundError 并发现我缺少 javax.el 依赖项。

所以最后我能够通过添加以下依赖项来解决NoClassDefFoundError 错误以及验证注释到架构生成中数据库约束的非翻译问题。

    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>3.0.0</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.el</artifactId>
        <version>3.0.0</version>
    </dependency>

【讨论】:

    猜你喜欢
    • 2022-08-15
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    相关资源
    最近更新 更多