Matching logical with hibernation

I have problems with sleep mode. I recently installed hbm2ddl for verification, and he complained a lot about the wrong data types. I fixed every problem except boolean ones.

I have an opener field in my class that displays as:

 <property column="opener" name="opener" type="boolean"/> 

The opener column is tinyint (4) and has a value of 1 or 0. So far, I have tried to change types, but to no avail. I also tried using the following setting in my hibernate.cfg:

 <property name="hibernate.query.substitutions">true 1, false 0</property> 

But I still get the same error. What am I doing wrong?

 org.hibernate.HibernateException: Wrong column type: opener, expected: bit at org.hibernate.mapping.Table.validateColumns(Table.java:261) at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1083) at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:116) at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:317) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294) at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859) 

Note. I do not have access to the database.

+7
source share
6 answers

If you cannot change your SQL type in your table, I recommend that you do this:

 <property name="opener" column="opener" type="path.to.your.package.YourClassUserType"/> 

and create your class:

 import org.hibernate.usertype.UserType; public class YourClassUserType implements UserType{ ... } 

you need to implement methods from the UserType interface. The implementation converts the byte to boolean (since TINYINT is displayed in the byte in Java)

see examples here

good luck :)

+4
source

For those who faced the same problems as me, I used a combination of the two answers posted here.

I applied a custom type to handle my tinyint field:

 public class TinyIntegerToBoolean implements UserType { public int[] sqlTypes() { return new int[]{Types.TINYINT}; } public Class returnedClass() { return Boolean.class; } public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor si, Object owner) throws HibernateException, SQLException { return (rs.getByte(names[0]) != 0); } public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor si) throws HibernateException, SQLException { st.setByte(index, Boolean.TRUE.equals(value) ? (byte) 1 : (byte) 0); } /* boilerplate... */ public boolean isMutable() { return false; } public boolean equals(Object x, Object y) throws HibernateException { if (x == null || y == null) { return false; } else { return x.equals(y); } } public int hashCode(Object x) throws HibernateException { assert (x != null); return x.hashCode(); } public Object deepCopy(Object value) throws HibernateException { return value; } public Object replace(Object original, Object target, Object owner) throws HibernateException { return original; } public Serializable disassemble(Object value) throws HibernateException { return (Serializable) value; } public Object assemble(Serializable cached, Object owner) throws HibernateException { return cached; } } 

Then I added the following to my mappings:

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <typedef class="com.test.model.TinyIntegerToBoolean" name="tinyint_boolean"/> </hibernate-mapping> 

Then in my opening field I use type=tinyint_boolean and it works like a charm :)

+4
source

You can define the DB column as char(1) , and in your Hibernate mapping file, define the property as type="yes_no" , which is the boolean type of Java. They will be displayed as Y and N values ​​in the database.

If you want to use tiny_int , then the size will be 1, but I'm not 100% sure how it appears in the HBM file.

+3
source

try the following:

 <property column="opener" name="opener" access="field" /> 

assuming you gotter getter

  boolean isOpener() ; 

and setter

 void setOpener(boolean b); 
+1
source

You can use numeric_boolean as a type:

 <property column="opener" name="opener" type="numeric_boolean"/> 
0
source

This is difficult because you do not have access to the database. But this can be done with a little work.

What you need to do is create a custom type class. This class will basically retrieve the value from the database (1 or 0), and it will contain logic that returns either a true or false Boolean object.

Here is an example:

http://alenovarini.wikidot.com/mapping-a-custom-type-in-hibernate

your mapping for your new type will look like this:

  <typedef class="com.path.to.my.package.CustomBooleanType" name="myBoolType" /> 

This class nullSafeGet method will return your boolean that will contain true or false.

so your new mapping will contain:

 <property column="opener" name="opener" type="myBoolType"/> 
0
source

All Articles