I am using Hibernate with Springs backed by a Mysql db.
Here is the entity similar to the one i use to make an entry
@Entity
@Table(name = "my_table") {
@Basic
@Column(name = "my_string", nullable = false)
private String myString;
}
The sql definition is
CREATE TABLE `my_table` (
`my_string` varchar(200) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Though the table allows null values, the column myString is non-nullable as per the JPA annotation. This is leading to unpredictable behaviour.
Q: Is the non-nullable ALWAYS enforced at the entity level while making inserts? Or is there some case in which it may be ignored
My expectation was that all of the entries should have been rejected. But with this setup, many entries (>7000) have gone into the table. Only sometimes i get a DataIntegrityViolation exception from spring
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)
....
I understand that having separate signature in the entity and the table is a bad practice, But i'm trying to identify what causes this behaviour and any other loopholes that might have been left out due to it.
Versions -
Mysql- 5.5
Hibernate - 4.0.0
Hibernate-jpa - 2.0
Spring-core- 3.1.0
Spring-jdbc- 3.1.2
@Column Annotation can have property "nullable" which can be set to true or false. This allows Hibernate to see whether nulls are to be stored or not.
The best way to avoid Hibernate's attempts at setting null values to primitives is to use Wrapper classes (Integer, Long, Double...); and especially, if you need to tack on a column or 2 to an existing table. Auto-boxing is your friend.
The @Column(nullable = false) Annotation It's used mainly in the DDL schema metadata generation. This means that if we let Hibernate generate the database schema automatically, it applies the not null constraint to the particular database column.
The JPA specification defines that during ordering, NULL values shall be handled in the same way as determined by the SQL standard. The standard specifies that all null values shall be returned before or after all non-null values. It's up to the database to pick one of the two options.
People frequently confuse the @Column(nullable) and @NotNull annotations.
The @Column(nullable)
is meant for the generated DDL scripts. But you don't use Hibernate to generate your DDL, so you shouldn't rely on it at all. What you want is @NotNull
which is a runtime validation trigger.
If you define the Hibernate Validator Annotation (or JPA 2.0 ones) you can get the DDL for those as well:
Out of the box, Hibernate (as of version 3.5.x) 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.
And make sure you enable validation if you're using JPA with Hibernate.
If you are using JPA 2 and Hibernate Validator is in the classpath the JPA2 specification requires that Bean Validation gets enabled. The properties javax.persistence.validation.group.pre-persist, javax.persistence.validation.group.pre-update and javax.persistence.validation.group.pre-remove as described in Section 10.1.2, “Hibernate event-based validation” can in this case be configured in persistence.xml. persistence.xml also defines a node validation-mode which can be set to AUTO, CALLBACK, NONE. The default is AUTO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With