2011-05-31 11 views
7

के साथ एक बूलियन मैपिंग मैं हाइबरनेट के साथ परेशानी में भाग रहा हूं। मैंने हाल ही में अपना एचबीएम 2ddl मान्य करने के लिए सेट किया है, और यह गलत डेटाटाइप के बारे में बहुत शिकायत कर रहा है। मैंने बूलियन को छोड़कर हर समस्या को ठीक किया है।हाइबरनेट

मैं अपने वर्ग है, जो के रूप में मैप किया गया है में एक क्षेत्र 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

आप अपनी तालिका में अपने एसक्यूएल प्रकार नहीं बदल सकते हैं, तो मैं तुम्हें यह करने के लिए सलाह देते हैं उपयोगकर्ता का प्रकार। कार्यान्वयन बाइट बूलियन के लिए (क्योंकि एक TINYINT जावा में बाइट में मैप किया गया है)

देख क्योंकि आप डेटाबेस के लिए कोई उपयोग कर सकते है examples here

सौभाग्य :)

3

आप अपने डीबी कॉलम को char(1) के रूप में परिभाषित कर सकते हैं और अपनी हाइबरनेट मैपिंग फ़ाइल में संपत्ति को type="yes_no" के रूप में परिभाषित कर सकते हैं, जो एक जावा बूलियन प्रकार है। ये डीबी में Y और N मानों के रूप में दिखाई देंगे।

यदि आप tiny_int का उपयोग करना चाहते हैं तो आकार 1 होना चाहिए, लेकिन मुझे 100% यकीन नहीं है कि यह एचबीएम फ़ाइल में कैसे मैप किया गया है।

+0

क्षमा करें, मुझे इसे थोड़ा और स्पष्ट करना होगा, लेकिन मेरे पास ओपी में डेटाबेस पर कोई नियंत्रण नहीं है। – Terraego

1

इस प्रयास करें:

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

यह सोचते हैं कि आप एक गेटर

boolean isOpener() ; 

और एक सेटर मिला

void setOpener(boolean b); 
+0

मुझे एक ही त्रुटि मिलती है, हालांकि – Terraego

+0

मदद करने के लिए धन्यवाद, अगर यह काम नहीं करता है, तो आपको TINYINT (4) के लिए TINYINT (4) बदलना होगा। – EricParis16

0

तुम एक प्रकार के रूप में numeric_boolean इस्तेमाल करने की कोशिश कर सकते हैं:

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

और अपने वर्ग बनाने: आप इंटरफ़ेस से तरीकों को लागू करना

import org.hibernate.usertype.UserType; 

public class YourClassUserType implements UserType{ 
... 
} 
+1

मुझे लगता है कि मैंने कहीं एक जेपीए एनोनेशन देखा है जिसने ऐसा कुछ किया है। यह मुझे मदद नहीं करता है, जब मैं सलामी बल्लेबाज को numeric_boolean के रूप में मैप करता हूं तो मुझे मिलता है: org.hibernate.MappingException: कॉलम के लिए numeric_boolean के लिए प्रकार निर्धारित नहीं कर सका: [org.hibernate.mapping.Column (सलामी बल्लेबाज)] – Terraego

0

यह एक मुश्किल से एक है बदलना होगा । लेकिन यह कुछ काम के साथ किया जा सकता है

आपको एक कस्टम टाइप क्लास बनाने की आवश्यकता होगी। यह वर्ग मूल रूप से डेटाबेस (1 या 0) से मान पुनर्प्राप्त करेगा और इसमें तर्क शामिल होगा जो या तो सत्य या गलत बूलियन ऑब्जेक्ट देता है।

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

अपने नए प्रकार की तरह दिखाई देगा के लिए अपने मानचित्रण:

यहाँ एक उदाहरण है

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

कक्षाएं nullSafeGet विधि अपने बूलियन उद्देश्य यह है कि सही या गलत में शामिल होंगे वापस आ जाएगी कि ।

तो अपने नए मैपिंग में शामिल होंगे:

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

किसी को जो मुझे के रूप में ही मुसीबत में भाग के लिए, मैं दो जवाब यहां पोस्ट का एक संयोजन का इस्तेमाल किया।

<?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 उपयोग करें और यह की तरह काम करता है:

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

तब मैं अपने मैपिंग के लिए निम्न कहा:

मैं अपने tinyint क्षेत्र को संभालने के लिए एक कस्टम प्रयोक्ता प्रकार लागू किया एक आकर्षण :)

+2

यदि यह डिफ़ॉल्ट तरीका है, तो आप अपने ऐप में बुलियन को मैप करना चाहते हैं और यदि आप हाइबरनेट 4 चला रहे हैं तो एक अच्छा विकल्प IMHO UserType के बजाय org.hibernate.type.BasicType को कार्यान्वित करना है और org.hibernate के साथ इस कार्यान्वयन को regsiter। type.BasicTypeRegistry। विशेष रूप से बेसिक टाइप # getRegistrationKeys नोट करें। आप जिस प्रकार की कुंजी को अपना प्रकार पंजीकृत करते हैं, उसके लिए आपका प्रकार डिफ़ॉल्ट प्रकार मैपिंग बन जाएगा। यहां आप इसे ["बूलियन", "java.lang.Boolean"] के तहत पंजीकृत करेंगे। Http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#types-registry –

+0

मैं हाइबरनेट 4.1 चला रहा हूं, यह बुलियन को मानचित्र करने का डिफ़ॉल्ट तरीका नहीं है, लेकिन इसका काफी उपयोग किया जाता है बहुत। उपरोक्त समाधान वास्तव में बदसूरत इमो है, इसलिए मैं जितनी जल्दी हो सके इसे देख सकता हूं, धन्यवाद! – Terraego

+0

तो getRegistrationKeys == ["tinyint_boolean"] के साथ बेसिक टाइप का उपयोग टाइपपीफ मैपिंग के बराबर होगा। –