Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 321
Aditya Avatar asked Jun 02 '14 13:06

Aditya


People also ask

What is nullable true in Hibernate?

@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.

How Hibernate handle null values?

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.

What is @column nullable false?

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.

How does JPA handle null values?

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.


1 Answers

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.

like image 188
Vlad Mihalcea Avatar answered Sep 27 '22 21:09

Vlad Mihalcea