我正在使用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;
虽然表允许空值,但myString列根据JPA注释是不可为空的。这导致了不可预测的行为。
问:在进行插入时,是否在实体级别强制执行不可为空的ALWAYS?或者是否存在可能被忽略的情况
我的期望是所有参赛作品都应该被拒绝。但是通过这种设置,许多条目(> 7000)进入了表格。 有时我只从Spring获得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
答案 0 :(得分:8)
人们常常混淆@Column(nullable) and @NotNull annotations。
@Column(nullable)
适用于生成的DDL脚本。但是你不能使用Hibernate生成你的DDL,所以你根本不应该依赖它。你想要的是@NotNull
,它是一个运行时验证触发器。
如果你定义了Hibernate Validator Annotation(或JPA 2.0)you can get the DDL for those as well:
开箱即用,Hibernate(版本3.5.x)将翻译 您为实体定义的映射元数据约束。 例如,如果您的实体的属性已注释@NotNull,则为 列将在生成的DDL模式中声明为非null 冬眠。
如果您正在使用带有Hibernate的JPA,请确保启用验证。
如果你使用的是JPA 2,那么Hibernate Validator就在classpath中了 JPA2规范要求启用Bean Validation。该 属性javax.persistence.validation.group.pre-persist, javax.persistence.validation.group.pre-update和 javax.persistence.validation.group.pre-remove,如章节中所述 10.1.2,“Hibernate基于事件的验证”在这种情况下可以在persistence.xml中配置。 persistence.xml还定义了一个节点 验证模式,可以设置为AUTO,CALLBACK,NONE。默认 是自动。