@NotNull 注释不会转换为模式生成中的非空约束
@NotNull annotation does not translate to not null constraint in schema generation
根据休眠验证程序参考文档 - 11.1.1 节。数据库模式级验证 (https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-checkconstraints-db),
Out of the box, Hibernate ORM will translate the constraints you have
defined for your entities into mapping metadata. For example, if a
property of your entity is annotated @NotNull, its columns will be
declared as not null in the DDL schema generated by Hibernate ORM.
但是当我用@NotNull 注释我的字段时,我没有自动获得架构级别的约束。
我尝试将 Environment.HBM2DDL_AUTO
设置为 update
和 create
,但两者都无法生成数据库约束。
即使休眠默认将 hibernate.validator.apply_to_ddl
设置为 true
,我什至尝试手动设置 -
settings.put("hibernate.validator.apply_to_ddl", true);
但是 none 这些选项似乎对我有用。
我的域名class
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;
}
MyPersistentclass
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;
}
你应该使用
@Column(nullable = false)
@NotNull 用于 Bean 验证,而不是模式约束,如果您使用的是旧版本的 hibernate @NotNull 将不会被转换为列约束
我犯了一个愚蠢的错误,因为我没有在 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>
根据休眠验证程序参考文档 - 11.1.1 节。数据库模式级验证 (https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-checkconstraints-db),
Out of the box, Hibernate ORM will translate the constraints you have defined for your entities into mapping metadata. For example, if a property of your entity is annotated @NotNull, its columns will be declared as not null in the DDL schema generated by Hibernate ORM.
但是当我用@NotNull 注释我的字段时,我没有自动获得架构级别的约束。
我尝试将 Environment.HBM2DDL_AUTO
设置为 update
和 create
,但两者都无法生成数据库约束。
即使休眠默认将 hibernate.validator.apply_to_ddl
设置为 true
,我什至尝试手动设置 -
settings.put("hibernate.validator.apply_to_ddl", true);
但是 none 这些选项似乎对我有用。
我的域名class
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;
}
MyPersistentclass
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;
}
你应该使用 @Column(nullable = false)
@NotNull 用于 Bean 验证,而不是模式约束,如果您使用的是旧版本的 hibernate @NotNull 将不会被转换为列约束
我犯了一个愚蠢的错误,因为我没有在 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>