Issue Details (XML | Word | Printable)

Key: HHH-468
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Scott Marlow
Reporter: Mark Matthews
Votes: 4
Watchers: 3
Operations

If you were logged in you would be able to see more operations.
Hibernate Core

MysqlDialect incorrectly maps java.lang.Boolean to SQL BIT

Created: 11/May/05 10:34 AM   Updated: 22/Jan/09 09:00 PM
Component/s: None
Affects Version/s: 3.0.3
Fix Version/s: None

Time Tracking:
Not Specified

Environment: Hibernate 3.0, MySQL.


 Description  « Hide
I didn't track down how java.lang.Boolean gets mapped to Types.BIT in hibernate, but you probably _don't_ want to map to "bit" like you do in MysqlDialect.

"bit", according to SQL99 (it's not in the core standard, and the type was actually dropped for sql2k3) is a bitfield, not a boolean value. You can of course define a bit(1), but it is technically more correct for java.lang.Boolean to map to a SQL BOOLEAN for MySQL since we support a BOOLEAN and a BIT.

It looks like the JDBC-3.0 guys ignored what the standard said, because in reality you'd want BIT to map to something like byte[], or java.util.BitSet if you were tracking how the SQL standard defines BIT.

I'm guessing you probably want to map to "boolean", which the JDBC driver will automagically convert for you, as it silently maps to TINYINT(1) on the server side.

 All   Comments   Work Log   Change History   FishEye      Sort Order: Ascending order - Click to sort in descending order
Mark Matthews added a comment - 11/May/05 12:08 PM
Looking through our manual, we're kind of being a bit goofy on this, as "BOOLEAN" doesn't exist in MySQL-4.0, so maybe BIT should be left, _or_ you can somehow work in a comment in your docs about the issue.

4.0 is technically "in retirement", so maybe this can be revisited later this summer when 5.0 goes GA.

Gavin King added a comment - 13/May/05 10:20 AM
Thanks for the advice Mark, but what *exactly* are you recommending?

I'll do whatever you tell us, I suppose ;)

Mark Matthews added a comment - 13/May/05 10:26 AM
Gavin,

I guess the trick is that before MySQL-5.0, you can use whatever you want, preferably "BIT", because that works with MySQL-4.0 and MySQL-4.1, and ends up being a synonym for TINYINT(1), which the driver will treat as java.sql.Types.BIT.

However starting with 5.0, the sql type "BIT" might not be the type people want, but "BOOLEAN" probably is.

Since as far as I can tell, you don't have version-specific dialects for schema export purposes (I might be missing something though), I suppose skip it for now.

Maybe HIB-3.1 could have version-specific schema export (you might want it for the new numeric types in Oracle 10g, and such too)?

From the JDBC side of things either would work, the driver will map them to java.lang.Boolean in either case.

If version-specific schema export isn't in the cards for awhile, maybe just a documentation note for schema export that MySQL-5.0 users might want to consider post-processing their schema files, converting BIT to BOOLEAN.

Gavin King added a comment - 13/May/05 10:49 AM
Well, we *do* have version-specific dialects for some databases, so we could do the same for MySQL. Only problem is, we already have two dialects (MyISAM vs InnoDB), so this change would mean *four* MySQL-specific dialects.

And it seems kinda a small thing (?), that the user can easily workaround by specifying sql-type="BOOLEAN".

I'm not sure...

Mark Matthews added a comment - 13/May/05 11:14 AM
> And it seems kinda a small thing (?), that the user can easily
> workaround by specifying sql-type="BOOLEAN".

Gavin, you're probably right. Is there any MySQL-specific dialect documentation where we can spell that out? I think that would be the most flexible, final solution.

The issue comes from the fact that not _all_ storage engines will support the BIT type in 5.0 for awhile, so users get errors such as the following (which Matt Raible pointed out, which caused this report):

https://appfuse.dev.java.net/servlets/ReadMsg?list=users&msgNo=6389

(fixed in MySQL-5.0.5 for everything but our cluster product right now, though).

Scott Marlow added a comment - 29/Sep/06 10:01 PM
Added MySQL5InnoDBDialect to resolve HHH-1891, so we could probably address HHH-468 with the new dialect.

Scott Marlow added a comment - 04/Oct/06 09:20 AM
If we map Types.BIT to MySQL Boolean in the new MySQL5InnoDBDialect, that wouldn't be schema compatable with the other MySQL dialects.

If a customer wants to create their own dialect, they could overide this mapping. Something easy like:

"
package org.hibernate.dialect;
import java.sql.Types;

public class MySQLCustom extends MySQL5InnoDBDialect {

public MySQLCustom() {
super();
registerColumnType( Types.BIT, "boolean" );
}
}
"

Perhaps we will do something in a future Hibernate release so that customers could specify the mapping a different way.

Lieven Doclo added a comment - 23/Jan/08 02:33 AM
To bring this issue back to life:

Can't we just map BIT to tinyint(1) in the MySQL dialect. This seems okay for all MySQL dialects (MyISAM and InnoDB).

One of the problems with bit in MySQL is that standard it's not show in a MySQL console. For example:

"select bitField from testTable" = field values not shown in console. You have to use "select BIT(bitField) from testTable" or "select bitField+0 from testTable" to show the values. When using tinyint(1), you don't encounter this problem.

So please fix this.

Laurent Mallet added a comment - 08/May/08 03:45 AM
Hi gavin,

My team is working with Seam and jboss 4.2 and discover this bug when we install our application on the pre-production plateform
on our entities objects.

Our pre-production and production plateforms are in RHEL 5. Our developpement plateform is on RHEL 4.
The main difference is also the MySQL version.

This bug is really annonying because :
- RHEL 5 install version 5 of MySQL (No support on MySQL 4)
- MySQL 4 is at end of his lifecycle
- in JPA, it's so ugly to change our code from boolean to int
- a search in google "MySQL 5 boolean BIT problem" shows so many desesperate people
- credibility of jboss : this bug is so annoying that my team doesn't understand that it could be possible; they are afraid that it could have
  other ugly bugs..

Laurent Mallet
CTO of Oxalya


Corey Lohman added a comment - 25/Jun/08 12:54 AM
To get booleans working without custom code this alias may be useful (works for MySQL -> HBM -> Java tooling):

1) represent booleans with TINYINT(1)

2) Add to cfg tinyInt1isBit=true & transformedBitIsBoolean=true:
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.tinyInt1isBit">true</property>
<property name="hibernate.connection.transformedBitIsBoolean">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

3) if running hbm2hbmxml, hbm2cfgxml, hbm2java use jdbcconfiguration, not configuration

One version set this worked on: JDK 1.5.0_09, Connect/J 5.1.6, Hibernate 3.2, Tools 3.2.2b1

Kaoru Shirai added a comment - 22/Jan/09 09:00 PM
> Can't we just map BIT to tinyint(1) in the MySQL dialect. This seems okay for all MySQL dialects (MyISAM and InnoDB).
> One of the problems with bit in MySQL is that standard it's not show in a MySQL console.

Me, too! I think this change does not affect seriously.
This problem is annoying many people:
[mysql bit hibernate boolean - Google Search]
http://www.google.com/search?q=mysql+bit+hibernate+boolean