52

Here is my JPA2 / Hibernate definition:

Code:
@Column(nullable = false)
private boolean enabled;

In MySql this column is resolved to a bit(1) datatype - which does not work for me. For legacy issues I need to map the boolean to a tinyint not to a bit. But I do not see a possibility to change the default datatype. Is there any?

Ta Sas
  • 8,699
  • 15
  • 45
  • 72

6 Answers6

66

@Type annotation is an Hibernate annotation.

In full JPA2 (with Hibernate 3.6+), the way to map a Boolean field to a TINYINT(1) SQL type instead of BIT(1), is to use the columnDefinition attribute.

@Column(nullable = false, columnDefinition = "TINYINT(1)")
private boolean enabled;

nb: length attribute seems to have no effect in this case, then we use (1) syntax.


With Hibernate 4.0+, this kind of syntax can cause an runtime error like this :

Wrong column type Found: bit, expected: TINYINT(1)

It seems that in this case, your only way is to use tinyInt1isBit=false in the MySQL datasource connection string like this :

jdbc:mysql://server_host:3306/database?tinyInt1isBit=false

By the way, you can now use the length attribute like this :

@Column(nullable = false, columnDefinition = "TINYINT", length = 1)
private boolean enabled;
Donatello
  • 2,597
  • 2
  • 22
  • 28
  • 3
    Since MySQL aliases `BOOLEAN` to `TINYINT(1)` one can also use `columnDefinition = "BOOLEAN"`, which might be a little more readable. – eggyal Sep 26 '13 at 09:29
  • you're right, you can also use the BOOLEAN alias with MySQL as long as the alias is realy set to TINYINT, which is true for now. By the way, BOOLEAN and TINYINT are both not standard SQL data types, so you take a risk of failure if you change your data provider dialect (ex: Oracle). – Donatello Jan 27 '14 at 14:16
  • 3
    `columnDefinition = "TINYINT", length = 1` is resulting column with :: `tinyint(4)` . what could be the reason? – gtiwari333 Aug 17 '16 at 12:46
44

Try the NumericBooleanType. For some reason this doesn't have a declared short type name so you'd have to use:

@Column(nullable = false)
@Type(type = "org.hibernate.type.NumericBooleanType")
private boolean enabled;

This does map to an INTEGER type but it will probably work fine with a TINYINT.

UPDATE: org.hibernate.type.NumericBooleanType Does not work with TINYINT in some RDBMS. Switch the database column type to INTEGER. Or use a different Java @Type value, or columnDefinition, as appropriate.

In this example, Dude's answer of @Column(nullable = false, columnDefinition = "TINYINT(1)") would work without any database changes.

Jon Adams
  • 22,969
  • 17
  • 78
  • 115
Mike Q
  • 21,350
  • 19
  • 80
  • 124
5

I'm using JPA with Spring Data/Hibernate 5.0 on a MySQL database.

In my Entity object, I put the following:

@Column(name = "column_name", columnDefinition = "BOOLEAN")
private Boolean variableName;

My dev environment has hibernate auto-ddl set to update, so when I deployed to dev, it created the table with column_name of type tinyint(1).

My code that uses this column considers null as false, so I'm not worried about nulls, if you are, you could make it a primitive boolean or add ", nullable = false" to the Column annotation.

This solution is fully JPA (doesn't use hibernate Type annotation) and requires no change to the connection string.

2

I had this error:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/config/context-config.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Could not determine type for: org.hibernate.type.NumericBooleanType, at table: bookingItem, for columns: [org.hibernate.mapping.Column(enabled)]

And this worked for me:

@Column(nullable = false, columnDefinition = "TINYINT(1)")
private boolean enabled;
dbmitch
  • 4,400
  • 4
  • 21
  • 37
  • That ended up working for me too. Not entirely sure why since I'm using the data type byte. I'm assuming because MySQL uses tinyint and not byte? Ref: @Column(name = "totalBeds", nullable = false, columnDefinition = "TINYINT(1)") private byte totalBeds; – coder3 Sep 03 '20 at 16:16
2

When using Microsoft sql and some versions of mysql use the following:

@Column(name = "eanbled", columnDefinition = "bit default 0", nullable = false)
private boolean enabled;

For me, tinybit, boolean, and other such definitions failed.

Nox
  • 896
  • 8
  • 23
0

Old question but probably will save someone's time.

I am using Spring Data JPA 2.2.5. I had a similar issue when I work with MySQL and MariadDB parallelly with the same code base. It worked on one and didn't on another.

The issue was, I was creating the field as unsigned.

I moved the below SQL part from

`is_fixed` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',

to the below

`is_fixed` TINYINT(1) NOT NULL DEFAULT '0',

this fixed the issue and was working in both Mysql and MariaDB without any issue...

BlueBird
  • 6,855
  • 7
  • 31
  • 58