2012-07-01 14 views
22

का उपयोग कर पोस्टग्रेएसक्यूएल में यूयूआईडी को कायम रखना मैं पोस्टग्रेएसक्यूएल में एक इकाई को जारी रखने की कोशिश कर रहा हूं जो यूयूआईडी को प्राथमिक कुंजी के रूप में उपयोग करता है। मैंने कोशिश की एक सादे UUID के रूप में यह बने है:जेपीए

@Id 
@Column(name = "customer_id") 
private UUID id; 
ऊपर के साथ

, मैं इस त्रुटि मिलती है:

ERROR: column "customer_id" is of type uuid but expression is of type bytea 
Hint: You will need to rewrite or cast the expression. 
Position: 137 

मैं भी कोई लाभ नहीं हुआ बाइट [] के रूप में UUID बने की कोशिश की:

@Transient 
private UUID id; 

@Id 
@Column(name = "customer_id") 
@Access(AccessType.PROPERTY) 
@Lob 
protected byte[] getRowId() { 
    return id.toString().getBytes(); 
} 

protected void setRowId(byte[] rowId) { 
    id = UUID.fromString(new String(rowId)); 
} 

अगर मैं @Lob को हटा देता हूं, तो मुझे जो त्रुटि मिलती है वह ऊपर पोस्ट की गई है। लेकिन @Lob के साथ लागू, त्रुटि के लिए थोड़ा परिवर्तन:

ERROR: column "customer_id" is of type uuid but expression is of type bigint 
Hint: You will need to rewrite or cast the expression. 
Position: 137 

मैं बहुत बुरा इस के रूप में सरल कुछ करने के लिए असमर्थ रहा महसूस कर रहा हूँ!

मैं हाइबरनेट 4.1.3 का उपयोग कर रहा हूं। PostgreSQL 9.1 के साथ अंतिम।

मैंने एक ही मुद्दे के साथ SO या अधिक पर कई प्रश्नों को देखा है लेकिन वे सभी पुराने हैं और कोई भी सीधे आगे जवाब नहीं देता है।

मैं बदसूरत हैक का उपयोग किये बिना इसे मानक तरीके से प्राप्त करना चाहता हूं। लेकिन अगर यह केवल (बदसूरत) हैक हासिल किया जा सकता है, तो हो सकता है कि मैं यही करूँगा। हालांकि, मैं डेटाबेस में यूयूआईडी को वर्चर के रूप में स्टोर नहीं करना चाहता क्योंकि यह प्रदर्शन के लिए अच्छा नहीं है। साथ ही, यदि संभव हो तो मैं अपने कोड में एक हाइबरनेट निर्भरता पेश नहीं करना चाहता हूं।

किसी भी मदद की सराहना की जाएगी।

UPDATE 1 (2012-07-03 12:15 बजे)

ठीक है, ठीक है, ठीक है ... यह बहुत मज़ेदार है कि मैं ठीक उसी कोड (सादा UUID, कोई रूपांतरण का परीक्षण किया है - एसक्यूएल सर्वर 2008 R2 JTDS ड्राइवर (v1.2.5) का उपयोग कर और, लगता है क्या, यह एक आकर्षण के रूप में काम के साथ कोड ऊपर तैनात) के पहले संस्करण (निश्चित रूप से मैं persistence.xml में कनेक्शन से संबंधित जानकारी बदलना पड़ा)।

अब, यह एक PostgreSQL विशेष मुद्दा या क्या है?

+1

[पोस्टग्रेस्क्ल यूयूआईडी द्वारा समर्थित हाइबरनेट द्वारा समर्थित डुप्लिकेट?] (Http://stackoverflow.com/questions/4495233/postgresql-uuid-supported-by -बिनेटनेट) –

+0

जैसा कि मैंने अपनी पोस्ट में उल्लेख किया है, वही समस्या के साथ SO पर कई प्रश्न हैं लेकिन वे सभी पुराने हैं और कोई भी अच्छा, कामकाजी समाधान नहीं प्रतीत होता है। आपके द्वारा उल्लिखित पोस्ट में कोई अपवाद नहीं है (जो, बीटीडब्ल्यू, मैंने अपना प्रश्न पोस्ट करने से पहले देखा था)। – ehsanullahjan

उत्तर

30

PostgreSQL JDBC ड्राइवर एक दुर्भाग्य से गैर JDBC-मानक प्रकार से कोड का प्रतिनिधित्व करने के लिए रास्ता चुन लिया है।वे बस उन सभी को नक्शा के लिए मानचित्र बनाते हैं। अन्यथा।

@Id 
@Column(name = "customer_id") 
@org.hibernate.annotations.Type(type="org.hibernate.type.PostgresUUIDType") 
private UUID id; 

या अधिक संक्षेप:

@Id 
@Column(name = "customer_id") 
@org.hibernate.annotations.Type(type="pg-uuid") 
private UUID id; 

एक और (बेहतर लंबी कहानी संक्षेप में, आप UUID मैपिंग से निपटने (postgres विशेष UUID डेटाप्रकार के स्तंभों के लिए) के लिए एक विशेष हाइबरनेट प्रकार मानचित्रण सक्षम करने की आवश्यकता) विकल्प java.util.UUID के रूप में उजागर सभी विशेषताओं के लिए डिफ़ॉल्ट हाइबरनेट प्रकार मैपिंग के रूप में org.hibernate.type.PostgresUUIDType को पंजीकृत करना है। यही कारण है कि दस्तावेज में @ कवर किया जाता है http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch06.html#types-registry

+1

+1 यह काम किया: @ org.hibernate.annotations.Type (type = "pg-uuid") – ehsanullahjan

+0

हाय, मैंने कोशिश की लेकिन मुझे एक org.hibernate मिला। मैपिंग अपवाद: जेडीबीसी प्रकार के लिए कोई डायलेक्ट मैपिंग नहीं: 1111. कोई भी कर सकता है मेरी मदद करो? – jonfornari

+0

@ जोनफोर्नारी मेरे पास एक ही समस्या थी लेकिन मेरी Grails परियोजना में org.hibernate.dialect.PostgreSQLDialect का चयन करना भूल गया। शायद आप उस या कुछ अन्य सेटिंग्स याद कर रहे हैं? मुझे निम्नलिखित की आवश्यकता नहीं थी, लेकिन यह आपकी मदद कर सकती है: http://andrew-arch.blogspot.com/2008/02/uuid-and-hibernate-second-update.html –

-4

मुझे यकीन है कि एक बार जब आप रिकॉर्ड के लिए यूयूआईडी उत्पन्न करते हैं, तो यह स्थिर होगा। इस प्रकार डेटाबेस के लिए एक वस्तु के रूप मानचित्रण UUID में कोई मतलब नहीं है और उसके बाद पुनः प्राप्ति पर स्ट्रिंग करने के लिए इसे परिवर्तित करने के लिए वापस।

उपयोग एक स्ट्रिंग रूप UUID:

  1. आईडी, UUID या दोनों का उपयोग करना है या नहीं:

    @Id 
    @Column(name = "customer_id") 
    private String id; 
    
    //getter and setter 
    
    public void setId(UUID id) { 
        this.id = id.toString(); 
    } 
    

    इसके अलावा कुछ बातों पर विचार करने के लिए कर रहे हैं। quick discussion over this है।

  2. बल्कि 'आईडी' से नाम के लिए 'UUID' का उपयोग करना, यह भ्रामक है।
  3. निकाला जा रहा है '-' UUID से संकेत, 4 बाइट सहेजें।
  4. @PrePersist खंड में उत्पन्न UUID यदि आप वसंत का उपयोग करें।
+0

आपके उत्तर के लिए धन्यवाद लेकिन ऐसा लगता है कि आप मेरे प्रश्न को पूरी तरह से नहीं गए हैं। मैंने पहले ही यूयूआईडी को एक स्ट्रिंग (वर्कर) के रूप में संग्रहीत करने का उल्लेख किया है, जो डाटाबेस में प्रदर्शन को नुकसान पहुंचाएगा ताकि विचार करने का विकल्प न हो। जब तक आप यूबीआईडी ​​को डीबी के देशी प्रकार (बनाम वर्चर) के रूप में संग्रहीत करते हैं, तब तक '-'s' के साथ खेलने की कोई ज़रूरत नहीं है। कोडिंगहोरर लिंक के लिए, मैं पहले से ही उस से गुजर चुका हूं। – ehsanullahjan

+0

इसके अलावा, यूयूआईडी-स्ट्रिंग-यूयूआईडी रूपांतरणों का पूरा कारण पहली बार त्रुटि को हल करना था। लेकिन, जैसा कि सवाल में बताया गया है, यह काम नहीं किया। – ehsanullahjan

+0

@janlala आप अभी भी लंबे समय तक आईडी बना सकते हैं, क्या यह प्रदर्शन को बचाएगा? – JMelnik

13

जेपीए 2.1 एक बहुत ही आसान तरीका PostgreSQL UUID स्तंभ प्रकार और java.util.UUID इसी इकाई क्षेत्र के प्रकार के रूप में उपयोग करने के लिए प्रदान करता है:

@javax.persistence.Converter(autoApply = true) 
public class PostgresUuidConverter implements AttributeConverter<UUID, UUID> { 

    @Override 
    public UUID convertToDatabaseColumn(UUID attribute) { 
     return attribute; 
    } 

    @Override 
    public UUID convertToEntityAttribute(UUID dbData) { 
     return dbData; 
    } 

} 

बस के लिए इस वर्ग को जोड़ने के अपने दृढ़ता विन्यास और @Column(columnDefinition="uuid") के साथ यूयूआईडी फ़ील्ड एनोटेट करें।

+0

इसके साथ कोई भाग्य नहीं है। @ कनवर्टर एनोटेशन कक्षा में लागू नहीं होता है। – ruckc

+0

मुझे यकीन नहीं है कि आपका क्या मतलब है। दोनों javax.persistence.Converter और org.eclipse.persistence.annotations.Converter एक कक्षा में लागू किया जा सकता है। मैंने यह स्पष्ट करने के लिए जवाब संपादित किया कि यह javax.persistence.Converter का उपयोग करता है। –

+0

यह काम किया (पीजी 9.4) - इसके अलावा @ कॉलम एनोटेशन मेरे लिए आवश्यक नहीं है। – Jack

1

समाधान ओलेग ने सुझाव दिया मेरे लिए पूरी तरह से काम नहीं किया है (यह विफल रहा है अगर आप एक शून्य मान लागू करने के लिए करने की कोशिश की)। यहां एक ट्वीड समाधान है जो शून्य मानों के लिए भी काम करता है।

मेरे मामले में मैं हालांकि EclipseLink उपयोग कर रहा हूँ, इसलिए यदि आप हाइबरनेट उपयोग कर रहे हैं तो आप इस आवश्यकता न पड़े। Postgresql JDBC ड्राइवर के

public class UuidConverter implements AttributeConverter<UUID, Object> { 
    @Override 
    public Object convertToDatabaseColumn(UUID uuid) { 
     PGobject object = new PGobject(); 
     object.setType("uuid"); 
     try { 
      if (uuid == null) { 
       object.setValue(null); 
      } else { 
       object.setValue(uuid.toString()); 
      } 
     } catch (SQLException e) { 
      throw new IllegalArgumentException("Error when creating Postgres uuid", e); 
     } 
     return object; 
    } 

    @Override 
    public UUID convertToEntityAttribute(Object dbData) { 
     return (UUID) dbData; 
    } 
} 
2

नया संस्करण >= 8.4-701 सही ढंग से java.util.UUID मानचित्रण संभाल। और इसलिए Hibernate >= 4.3.x करें।

https://stackoverflow.com/a/780922/173149 पर विवरण देखें:

Map the database uuid type to java.util.UUID. 
This only works for relatively new server (8.3) and JDK (1.5) versions. 
5

यह हाइबरनेट 5.1.x के साथ काम करने के लिए आपको स्टीव Ebersole comment here

@Id 
@GeneratedValue 
@Column(columnDefinition = "uuid", updatable = false) 
public UUID getId() { 
    return id; 
} 
+0

अगर मैं कर सकता तो मैं इस जवाब के लिए दो बार आवाज उठाऊंगा। स्तंभ परिभाषा विनिर्देश ने मुझे एक मुद्दा हल किया जब टेबल निर्माण के दौरान यूयूआईडी को ज्यामिति प्रकार से प्रतिस्थापित किया गया था। ऐसा इसलिए हुआ क्योंकि PostgisDialect का उपयोग किया गया था। –

0

PostgreSQL यूआरएल कनेक्शन पर इस ध्वज जोड़ता है का पालन कर सकते हैं:? Stringtype = अनिर्दिष्ट

जैसे

jdbc: postgresql: // localhost: 5432/yourdatabase? Stringtype = unspecified

+0

हालांकि यह सवाल का जवाब दे सकता है, उत्तर के आवश्यक हिस्सों को समझाना बेहतर है और संभवतः ओपीएस कोड के साथ समस्या क्या थी। – pirho