13

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
Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
Aditya
  • 2,148
  • 3
  • 21
  • 34
  • 1
    It may be a personal choice due to some specific business rules otherwise we should always keep table column and entity field's check or constraint behavior same because this is common that our table may be accessed by some other application and/or direct sql scripts as well where such application constraints rule will fail, I am not sure something similar has cause this problem to you as well. – Kalher Jun 02 '14 at 14:02
  • 1
    I overlooked it while making the entity initially. I've corrected it now. But I'm sure that no other script or application accesses this table. So i want to know how something like this could happen. – Aditya Jun 02 '14 at 14:11

1 Answers1

9

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.

Community
  • 1
  • 1
Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
  • i read that link, but i was still confused as to why the behaviour is different in different instances. Shouldn't it be uniform through all runs? – Aditya Jun 03 '14 at 10:24
  • Some settings are already legacy and changing "old settings" may break many existing products. That's why you have better freedom with the new ones (NotNull bean validation). The Column nullable setting dates back to Hibernate origins while the Bean Validator has found its way after the Hibernate Validator project emerged and the JPA specs adopted this feature. – Vlad Mihalcea Jun 03 '14 at 12:49
  • But will the behaviour change during the runtime of the same process? The process in question was not even restarted. – Aditya Jun 03 '14 at 14:07