2011-05-31 71 views
7

我遇到了休眠問題。我最近設置了我的hbm2ddl進行驗證,並且一直在抱怨錯誤的數據類型。我已經修復了除布爾值之外的所有問題。用休眠映射布爾值

我有一個字段opener在我的類,它被映射爲:

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

opener是一個tinyint (4)並具有到目前爲止,我已經試圖改變類型的1或0的值,但無濟於事。我也嘗試在我的hibernate.cfg中使用以下設置:

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

但是我仍然收到相同的錯誤。我究竟做錯了什麼?

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) 

注意:我沒有訪問數據庫的權限。

回答

4

如果你不能在你的表改變你的SQL類型,我建議你這樣做:

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

和創建類:

import org.hibernate.usertype.UserType; 

public class YourClassUserType implements UserType{ 
... 
} 

你必須實現從接口方法用戶類型。 的實施將改變字節爲布爾(因爲TINYINT以字節映射在Java中)

看到examples here

好運:)

3

您可以將您的數據庫列定義爲char(1),並在您的Hibernate映射文件中將該屬性定義爲type="yes_no",這是一個Java布爾類型。這些將在數據庫中顯示爲YN值。

如果你想使用tiny_int那麼尺寸必須是1,但我不是100%確定它是如何映射到HBM文件中的。

+0

對不起,我必須有一個更清晰的狀態,但我沒有控制數據庫,它在OP中。 – Terraego 2011-05-31 18:06:46

1

試試這個:

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

假設你有一個getter

boolean isOpener() ; 

和二傳手

void setOpener(boolean b); 
+0

我得到了同樣的錯誤,謝謝你幫忙,雖然 – Terraego 2011-06-01 07:50:30

+0

如果不起作用,你必須改變你的TINYINT(4)TINYINT(1)。 – EricParis16 2011-06-01 15:41:42

0

你可以嘗試使用numeric_boolean作爲一個類型:

<property column="opener" name="opener" type="numeric_boolean"/> 
+1

我想我已經看到了jpa annonation做了這樣的事情。當我將opener類型映射爲一個numeric_boolean時,我得到: org.hibernate.MappingException:無法確定類型:numeric_boolean,列:[org.hibernate.mapping.Column(opener)] – Terraego 2011-06-01 07:48:44

0

這是一個棘手的,因爲你對數據庫沒有訪問。但它可以通過一些工作完成

你需要做的是創建一個自定義類型類。這個類將基本上從數據庫中檢索值(1或0),它將包含返回true或false布爾對象的邏輯。

下面是一個例子:

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

你對你的新類型看起來像映射:

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

的類nullSafeGet方法將返回你的Boolean對象包含true或false 。

因此新的映射將包含:

<property column="opener" name="opener" type="myBoolType"/> 
4

對於任何人誰遇到同樣麻煩的,因爲我,我這裏使用的貼兩個答案的組合。

我實現了一個自定義的用戶類型來處理我的TINYINT領域:

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; 
    } 
} 

然後添加以下到我的映射:

<?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> 

然後在我的揭幕戰現場我用type=tinyint_boolean,它的工作原理是一個魅力:)

+2

如果這是你想要在你的應用中映射布爾值的默認方式,並且如果你碰巧正在運行Hibernate 4,一個更好的替代方案是恕我直言,即實現org.hibernate.type.BasicType而不是UserType,並使用org.hibernate註冊此實現。 type.BasicTypeRegistry。特別注意BasicType#getRegistrationKeys。您的類型將成爲您在任何鍵下注冊您的類型的默認類型映射。這裏你可以在[「boolean」,「java.lang.Boolean」]下注冊它。請參閱http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#types-registry – 2012-05-31 04:34:20

+0

我正在運行hibernate 4.1,它不是映射布爾值的默認方式,但它的使用頗爲流行很多。上面的解決方案真的很難看,所以我儘快查看,謝謝! – Terraego 2012-05-31 08:47:29

+0

因此,使用BasicType和getRegistrationKeys == [「tinyint_boolean」]將等同於typedef映射。 – 2012-05-31 11:25:59