Hibernate, Boolean Fields, and MySQL 5.x

There's a problem persisting boolean fields using Hibernate 3.2.2 to MySQL 5.0, if you allow Hibernate to generate your schema, and you leave Hibernate to generate the schema in the default way. It works fine on MySQL 4.1 and it doesn't matter if you use boolean (primitive) or Boolean (object) types for the fields.

With a class such as:

public class MyObject {
   protected boolean myField;
   public boolean getMyField() { return myField; }
   public void setMyField(boolean x) { myField = x; }
}

And a Hibernate mapping such as:

<property name="myField" column="my_field" not-null="true" />

And allow Hibernate to generate the schema on startup, e.g. by writing the following in the "hibernate.cfg.xml" file:

<property name="hbm2ddl.auto">create</property>

Against MySQL 4.1 this all works, and the column has the data type tinyint(1). But in MySQL 5.0 the data type is bit(1) (which seems logical enough) but Hibernate then throws the following unhelpful exception upon every insert:

could not insert: [com.company.MyObject]
org.hibernate.exception.DataException: could not insert: [com.company.MyObject]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:77)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
....
Caused by: java.sql.SQLException: Data too long for column 'my_field' at row 1
at ....

The solution is to change the Hibernate mapping for the field to this:

<property name="myField" not-null="true" >
   <column sql-type="BOOLEAN" not-null="true" name="my_field" />
</property>

Then the field is generated as tinyint(1) and then it all works fine again.

P.S. I recently created a nerdy privacy-respecting tool called When Will I Run Out Of Money? It's available for free if you want to check it out.

This article is © Adrian Smith.
It was originally published on 4 Jul 2007
More on: FAIL | Hibernate