2011-02-26 8 views
8

पर मैपिंग का उपयोग करके मैं अपने डोमेन ऑब्जेक्ट्स के लिए आईडी के लिए यूयूआईडी का उपयोग करना चाहता हूं। विचार यह है कि यूयूआईडी एक ग्राहक द्वारा प्रदान की जा सकती है और यदि यूयूआईडी उत्पन्न नहीं किया जाएगा। मैं बहुत तरह के रूप में परिभाषा है:यूआईआईडी का उपयोग आईडी के रूप में और बाइनरी कॉलम

class Person { 
     static mapping = { 
     id generator:'assigned' 
     } 

     String id 

     def getUUID ={ 
      return java.util.UUID.randomUUID().toString(); 
     } 


      transient beforeInsert = { 
      if (id == null || id.equals("")) 
         id = getUUID(); 
      } 
} 

अब यह सोचते हैं मैं डैश बाहर है कि जावा UUID या ग्राहक UUID प्रदान की में शामिल हैं पट्टी मैं चाहूँगा यह मेरा MySQL डेटाबेस में एक द्विआधारी क्षेत्र में संग्रहीत करने के लिए । और पुनर्प्राप्ति पर भी वापस भेजने के लिए सही प्रारूप है।

मैं इसे कैसे पूरा कर सकता हूं? ऐसा करने के बेहतर तरीके पर विचार?

उत्तर

3

ग्रेल्स और हाइबरनेट आमतौर पर यूयूआईडी को अपने स्ट्रिंग फॉर्म में संभालते हैं। थोड़ा और काम के साथ बाइनरी यूयूआईडी का उपयोग करना संभव है। को UUID टाइप करने के लिए घोषित करें और बाइट्स की सरणी के रूप में इसे क्रमबद्ध करने के लिए एक हाइबरनेट उपयोगकर्ता प्रकार प्रदान करें। आपको यूआईआईडी के लिए एसक्यूएल प्रकार का उपयोग करने के लिए grails को बताने की भी आवश्यकता होगी। उदाहरण के लिए:

class Person { 
    static mapping = { 
     id generator:'assigned', type: UUIDUserType, sqlType: 'varbinary(16)' 
    } 

    UUID id 

    def beforeInsert = { 
     if (!id) { 
      id = UUID.randomUUID() 
     } 
    } 
} 

UUID के लिए उपयोगकर्ता प्रकार है:

import java.nio.ByteBuffer 
import java.nio.LongBuffer 
import java.sql.ResultSet 
import java.sql.PreparedStatement 
import java.sql.Types 
import org.hibernate.usertype.UserType 

public class UUIDUserType implements UserType { 

    int[] sqlTypes() { [Types.VARBINARY] as int [] } 
    Class returnedClass() { UUID } 

    Object nullSafeGet(ResultSet resultSet, String[] names, owner) { 
     byte[] value = resultSet.getBytes(names[0]) 
     return value ? bytesToUuid(value) : null 
    } 

    void nullSafeSet(PreparedStatement statement, value, int index) { 
     if (value == null) { 
       statement.setNull(index, Types.VARBINARY) 
     } else { 
       statement.setBytes(index, uuidToBytes(value)) 
     } 
    } 

    boolean equals(x, y) { x == y } 
    int hashCode(x) { x.hashCode() } 
    Object deepCopy(value) { value } 
    boolean isMutable() { false } 
    Serializable disassemble(value) { value } 
    Object assemble(Serializable cached, owner) { cached } 
    def replace(original, target, owner) { original } 

    static byte[] uuidToBytes(uuid) { 
     def bytes = new byte[16]; 
     ByteBuffer.wrap(bytes).asLongBuffer().with { 
      put(0, uuid.mostSignificantBits) 
      put(1, uuid.leastSignificantBits) 
     } 
     bytes 
    } 

    static UUID bytesToUuid(bytes) { 
     ByteBuffer.wrap(bytes).asLongBuffer().with { 
      new UUID(get(0), get(1)) 
     } 
    } 
} 
+0

MySQL पर काम नहीं करता है कि: 2011-02-27 10: 18: 33,818 [मुख्य] ​​त्रुटि hbm2ddl.SchemaExport - असफल: बनाने टेबल व्यक्ति (आईडी tinyblob शून्य नहीं, संस्करण बिगिन नल, प्राथमिक कुंजी (आईडी)) 2011-02-27 10: 18: 33,819 [मुख्य] ​​ERROR hbm2ddl.SchemaExport - BLOB/टेक्स्ट कॉलम 'आईडी' बिना कुंजी विनिर्देश में उपयोग किया जाता है एक मुख्य लंबाई 2011-02-27 10: 18: 36,702 [मुख्य] ​​त्रुटि का उपयोग। जेडीबीसीएक्सप्शन रिपोर्टर - तालिका 'testuuid.person' मौजूद नहीं है – imrank1

+0

ओह, आप सही हैं। मुझे लगता है कि grails स्वचालित रूप से गैर स्ट्रिंग यूयूआईडी संभालती है, लेकिन यह पता चला है कि यह नहीं करता है। मैंने एक फिक्स के साथ जवाब अद्यतन किया है। – ataylor

+0

आह हाँ एक कस्टम usertype। मैंने सोचा होगा कि grails या हाइबरनेट ने हमारे लिए इसका ख्याल रखा होगा। कुल मिलाकर समाधान काम करता है..जो भी grails/hibernate संबंधित के लिए एक समस्या है समस्या के लिए varbinary (16) इकाइयों के लिए प्राथमिक कुंजी के रूप में उपयोग करते समय। एकमात्र समाधान मैन्युअल रूप से डेटाबेस योजना बनाने के लिए प्रतीत होता है। – imrank1

संबंधित मुद्दे