休眠处理 nullable=true 在 @Column

2022-09-04 22:32:59

我正在使用Hibernate和由Mysql db支持的Springs。

这是类似于我用来制作条目的实体

@Entity
@Table(name = "my_table") {

    @Basic
    @Column(name = "my_string", nullable = false)
    private String myString;
}

sql 的定义是

CREATE TABLE `my_table` (
 `my_string` varchar(200) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

尽管该表允许空值,但根据 JPA 注释,myString 列是不可为空的。这导致了不可预测的行为。

问:在进行插入时,是否始终在实体级别强制执行不可为空的值?或者在某些情况下,它可能被忽略

我的期望是,所有的参赛作品都应该被拒绝。但是通过此设置,许多条目(>7000)已进入表中。只有有时我从春天得到一个DataIntegrityViolation异常

org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: ...; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: ....
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:652)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:104)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58) 
    ....  
    ....
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: ....
    at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:103)
    ....

我知道在实体和表中使用单独的签名是一种不好的做法,但是我试图找出导致这种行为的原因以及可能因此而被遗漏的任何其他漏洞。

Versions -
Mysql- 5.5
Hibernate - 4.0.0
Hibernate-jpa - 2.0
Spring-core- 3.1.0
Spring-jdbc- 3.1.2

答案 1

人们经常混淆@Column(nullable)和@NotNull注释

适用于生成的 DDL 脚本。但是您不使用Hibernate来生成DDL,因此您根本不应该依赖它。您需要的是一个运行时验证触发器。@Column(nullable)@NotNull

如果您定义了Hibernate Validator Annotation(或JPA 2.0注释),您也可以获得这些注释的DDL

开箱即用的Hibernate(从版本3.5.x开始)会将您为实体定义的约束转换为映射元数据。例如,如果实体的属性@NotNull注释,则其列将在 Hibernate 生成的 DDL 架构中声明为不为 null。

如果您将 JPA 与 Hibernate 一起使用,请确保启用验证。

如果您使用的是 JPA 2 并且休眠验证器位于类路径中,那么 JPA2 规范要求启用 Bean 验证。第 10.1.2 节 “基于事件的休眠验证”中所述的属性 javax.persistence.validation.group.pre-persist、javax.persistence.validation.group.pre-remove,在这种情况下,可以在持久性.xml中配置。持久性.xml还定义了一个节点验证模式,该模式可以设置为AUTO,CALLBACK,NONE。默认值为“自动”。


答案 2

推荐