Aditya
Aditya

Reputation: 2246

Hibernate handling of nullable=true in @Column

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

Upvotes: 13

Views: 29967

Answers (1)

Vlad Mihalcea
Vlad Mihalcea

Reputation: 153780

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.

Upvotes: 9

Related Questions