बाइट के लिए उचित हाइबरनेट एनोटेशन []


120

मेरे पास हाइबरनेट 3.1 और जेपीए एनोटेशन का उपयोग करने वाला एक एप्लिकेशन है। इसकी बाइट के साथ कुछ वस्तुएं हैं [] विशेषताएँ (1k - 200k आकार में)। यह JPA @Lob एनोटेशन का उपयोग करता है, और हाइबरनेट 3.1 सभी प्रमुख डेटाबेस पर इन्हें ठीक पढ़ सकता है - यह JDBC ब्लॉब विक्रेता विशिष्टताओं को छिपाने के लिए लगता है (जैसा कि यह करना चाहिए)।

@Entity
public class ConfigAttribute {
  @Lob
  public byte[] getValueBuffer() {
    return m_valueBuffer;
  }
}

हमें 3.5 में अपग्रेड करना पड़ा, जब हमें पता चला कि हाइबरनेट 3.5 टूटता है (और ठीक नहीं होगा) पोस्टग्रैसक्ल में यह एनोटेशन संयोजन (बिना वर्कअराउंड के)। मुझे अब तक स्पष्ट रूप से ठीक नहीं मिला है, लेकिन मैंने नोटिस किया है कि अगर मैं सिर्फ @ लोब को हटाता हूं, तो यह पोस्टग्रेजल टाइप बाइटा का उपयोग करता है (जो काम करता है, लेकिन केवल पोस्टग्रेज पर)।

annotation                   postgres     oracle      works on
-------------------------------------------------------------
byte[] + @Lob                oid          blob        oracle
byte[]                       bytea        raw(255)    postgresql
byte[] + @Type(PBA)          oid          blob        oracle
byte[] + @Type(BT)           bytea        blob        postgresql

once you use @Type, @Lob seems to not be relevant
note: oracle seems to have deprecated the "raw" type since 8i.

मैं एक एकल एनोटेट वर्ग (एक ब्लॉब प्रॉपर्टी के साथ) का रास्ता खोज रहा हूं जो प्रमुख डेटाबेस में पोर्टेबल है।

  • एक बाइट [] संपत्ति को एनोटेट करने का पोर्टेबल तरीका क्या है?
  • क्या यह हाइबरनेट के कुछ हालिया संस्करण में तय किया गया है?

अद्यतन: इस ब्लॉग को पढ़ने के बाद मैंने आखिरकार यह पता लगा लिया है कि JIRA मुद्दे में मूल वर्कअराउंड क्या था: जाहिरा तौर पर आपको @Lob को छोड़ना होगा और संपत्ति को एनोटेट करना होगा:

@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType") 
byte[] getValueBuffer() {...

हालांकि, यह मेरे लिए काम नहीं करता है - मैं अभी भी बाइट के बजाय ओआईडी प्राप्त करता हूं; हालांकि इसने JIRA मुद्दे के लेखक के लिए काम किया, जो ओईद चाहते थे।

ए। गार्सिया के जवाब के बाद, मैंने फिर इस कॉम्बो की कोशिश की, जो वास्तव में पोस्टग्रैस्कल पर काम करता है, लेकिन ओरेकल पर नहीं।

@Type(type="org.hibernate.type.BinaryType") 
byte[] getValueBuffer() {...

मुझे वास्तव में क्या करने की आवश्यकता है जो नियंत्रित करता है जो @ org.hibernate.annotations.Type संयोजन (@Lob + बाइट [] मैप हो जाता है) से (पोस्टग्रैसेकल पर)।


यहाँ 3.5.5 से स्निपेट है। MaterializedBlobType (sql type Blob) से। स्टीव के ब्लॉग के अनुसार, postgresql चाहता है कि आप धाराओं का उपयोग bytea के लिए करें (मुझसे क्यों न पूछें) और ogresql के कस्टम ब्लॉब प्रकार को oids के लिए पोस्ट करें। यह भी ध्यान दें कि JDBC पर setBytes () का उपयोग करना भी bytea (पिछले अनुभव से) के लिए है। तो यह बताता है कि क्यों उपयोग-धाराओं का कोई प्रभाव नहीं पड़ता है कि वे दोनों 'बायटिया' मान लेते हैं।

public void set(PreparedStatement st, Object value, int index) {
 byte[] internalValue = toInternalFormat( value );
 if ( Environment.useStreamsForBinary() ) {
  // use streams = true
   st.setBinaryStream( index, 
    new ByteArrayInputStream( internalValue ), internalValue.length );
 }
 else {
  // use streams = false
  st.setBytes( index, internalValue );
 }
}

इसका परिणाम यह होगा:

ERROR: column "signature" is of type oid but expression is of type bytea

अद्यतन अगला तार्किक प्रश्न है: "क्यों न केवल तालिका परिभाषाओं को मैन्युअल रूप से बाइटी में बदलें" और (@Lob + बाइट []) रखें? यह काम करता है , UNTIL आप एक सुस्त बाइट [] को स्टोर करने का प्रयास करते हैं। जो पोस्टग्रेसीएल चालक सोचता है कि यह एक ओआईडी प्रकार की अभिव्यक्ति है और कॉलम प्रकार बाइटा है - इसका कारण यह है कि हाइबरनेट (सही तरीके से) JDBC.setNull () के बजाय JDBC.setBytes (नल) को कॉल करता है जो PG ड्राइवर की अपेक्षा करता है।

ERROR: column "signature" is of type bytea but expression is of type oid

हाइबरनेट में प्रकार प्रणाली वर्तमान में 'कार्य प्रगति पर है' (3.5.5 पदावनति टिप्पणी के अनुसार)। वास्तव में 3.5.5 कोड में से बहुत कुछ हटा दिया गया है, यह जानना मुश्किल है कि पोस्टग्रेक्यूएलडायल को उप-वर्गीकृत करते समय क्या देखना है।

AFAKT, Types.BLOB / 'oid' को postgresql पर कुछ कस्टम प्रकार से मैप किया जाना चाहिए जो OID स्टाइल JDBC एक्सेस (यानी PostgresqlBlobType ऑब्जेक्ट और NOT MaterializedBlobbype) का उपयोग करता है। मैंने वास्तव में कभी भी ब्लब्स को पोस्टग्रेजेकल के साथ सफलतापूर्वक इस्तेमाल नहीं किया है, लेकिन मुझे पता है कि बाइटिया बस एक के रूप में काम करता है / मैं उम्मीद करूंगा।

मैं वर्तमान में BatchUpdateException को देख रहा हूं - यह संभव है कि ड्राइवर बैचिंग का समर्थन न करे।


2004 के महान उद्धरण: "मेरी रम्बलिंग का योग करने के लिए, मैं कहूंगा कि हमें Hibernate को बदलने से पहले JDBC ड्राइवर के लिए LOB को ठीक से करने के लिए इंतजार करना चाहिए।"

संदर्भ:


ऐसा लगता है कि 3.6 में तय किया गया है, 3.5.6 के बारे में निश्चित नहीं है; MaterializedBlobType वर्ग 3.5.5> 3.6 से पूरी तरह से फिर से लिखा गया था। ओआईडी प्रकार अब काम करता है क्योंकि उन्होंने कार्यान्वयन को बदल दिया है।
जस्टिन

अच्छा! मुझे आश्चर्य है कि जीरा मुद्दा इस पुनर्लेखन को ट्रैक कर रहा है, यदि कोई हो (शायद फिर से लिखना एक गहरे बदलाव का परिणाम है)। यदि संभव हो तो 3.5 में हुए बदलावों का समर्थन करना अच्छा होगा। बुरी खबर अगर यह संभव नहीं है।
पास्कल थिवेंट

वास्तव में मेरे परीक्षण ने मुझे पहली बार एक झूठी सकारात्मक जानकारी दी (मुझे पता था कि मुझे इंतजार करना चाहिए!) - इसका अभी भी तय नहीं किया गया है, बग को अभी-अभी BlobTypeDescriptor में स्थानांतरित किया गया है।
जस्टिन

धन्यवाद। @ टाइप (प्रकार = "org.hibernate.type.BinaryType") ने मेरे लिए एक ऐसी तालिका के लिए काम किया जो पीडीएफ फाइलों को स्टोर करती है। मैंने Oracle से Postgres के लिए एक डेटाबेस माइग्रेट किया था Oracle से बुद्धिमान पोस्टर्स से Oracle-To-PostgreSQL का उपयोग कर, और यह स्वचालित रूप से परिवर्तित हो गया और BLOB से BYTEA में डाला गया, लेकिन BlobType ने मेरे लिए काम नहीं किया।
जमरान

जवाबों:


68

एक बाइट [] संपत्ति को एनोटेट करने का पोर्टेबल तरीका क्या है?

आपको क्या चाहिए इस पर यह निर्भर है। JPA एक गैर एनोटेट को जारी रख सकता है byte[]। JPA 2.0 कल्पना से:

11.1.6 बेसिक एनोटेशन

Basicएनोटेशन एक डेटाबेस स्तंभ के लिए मानचित्रण का सरलतम प्रकार है। Basicएनोटेशन निम्नलिखित प्रकार के किसी भी एक लगातार संपत्ति या उदाहरण वैरिएबल पर लागू किया जा सकता है: जावा आदिम, प्रकार, आदिम प्रकार के रैपर, java.lang.String, java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp, byte[],Byte[] , char[], Character[], enums, और किसी भी अन्य प्रकार है कि औजार Serializable। जैसा कि धारा 2.8 में वर्णित है, Basicएनोटेशन का उपयोग इन प्रकारों के लगातार क्षेत्रों और गुणों के लिए वैकल्पिक है। यदि इस तरह के क्षेत्र या संपत्ति के लिए बेसिक एनोटेशन निर्दिष्ट नहीं है, तो बेसिक एनोटेशन के डिफ़ॉल्ट मान लागू होंगे।

और हाइबरनेट इसे "डिफ़ॉल्ट रूप से" एक SQL VARBINARY(या आकार के LONGVARBINARYआधार पर एक SQL Column?) के साथ मैप करेगा ?bytea

लेकिन अगर आप byte[]बड़े ऑब्जेक्ट में संग्रहित होना चाहते हैं, तो आपको एक का उपयोग करना चाहिए @Lob। युक्ति से:

11.1.24 लोब एनोटेशन

एक Lobएनोटेशन निर्दिष्ट करता है कि डेटाबेस-समर्थित बड़ी ऑब्जेक्ट प्रकार के लिए एक निरंतर संपत्ति या फ़ील्ड को एक बड़ी वस्तु के रूप में जारी रखा जाना चाहिए। पोर्टेबल एप्लिकेशन को Lobडेटाबेस Lobप्रकार पर मैपिंग करते समय एनोटेशन का उपयोग करना चाहिए । Lobएनोटेशन मूल टिप्पणी के साथ या के साथ संयोजन के रूप में इस्तेमाल किया जा सकता ElementCollectionएनोटेशन जब तत्व संग्रह मूल्य बुनियादी प्रकार का है। एक Lobया तो एक द्विआधारी या चरित्र प्रकार हो सकता है। Lobप्रकार लगातार क्षेत्र या संपत्ति के प्रकार से अनुमान लगाया और स्ट्रिंग और चरित्र प्रकार, ब्लॉब को चूक के लिए छोड़कर, है।

और हाइबरनेट इसे SQL पर मैप करेगा BLOBजिसे PostgreSQL एक के साथ हैंडल करता है oid

क्या यह हाइबरनेट के कुछ हालिया संस्करण में तय किया गया है?

खैर, समस्या यह है कि मुझे नहीं पता कि समस्या वास्तव में क्या है। लेकिन मैं कम से कम यह कह सकता हूं कि 3.5x.x शाखा में 3.5.0-बीटा -2 (जो कि जहां एक परिवर्तित रूप में पेश किया गया है) से कुछ भी नहीं बदला है।

लेकिन HHH-4876 , HHH-4617 और PostgreSQL और BLOBs (के javadoc में उल्लिखित PostgreSQLDialect) जैसे मुद्दों के बारे में मेरी समझ यह है कि आप निम्नलिखित संपत्ति सेट करने वाले हैं

hibernate.jdbc.use_streams_for_binary=false

यदि आप oidयानी के byte[]साथ प्रयोग करना चाहते हैं @Lob(जो मेरी समझ हैVARBINARY है कि आप ओरेकल के साथ नहीं चाहते हैं)। क्या आपने यह कोशिश की?

एक विकल्प के रूप में, HHH-4876 पदावनत का उपयोग करने का सुझाव देता हैPrimitiveByteArrayBlobType पुराने व्यवहार (पूर्व हाइबरनेट 3.5) प्राप्त करने के लिए ।

संदर्भ

  • JPA 2.0 विशिष्टता
    • खंड 2.8 "गैर-संबंध क्षेत्रों या गुणों के लिए मानचित्रण चूक"
    • धारा 11.1.6 "मूल व्याख्या"
    • धारा 11.1.24 "लोब एनोटेशन"

साधन


OMG, मुझे एहसास है कि जब से मैंने जवाब देना शुरू किया है तब से यह सवाल बहुत बदल गया है। बाद में सभी परिवर्तनों को पढ़ेंगे और यदि आवश्यक हो तो परिवर्तनों को पचाने के बाद मेरे उत्तरों को अपडेट करेंगे।
पास्कल थिवेंट

कल्पना को देखने के लिए अच्छा है, इसलिए हाइबरनेट एक बड़े आकार के समर्थित प्रकार के नक्शे (@Lob + बाइट []) के लिए पूरी तरह से सही है। Postgresql में 2 (bytea या oid) हैं। हालाँकि, हाइबरनेट 3.5 मैप्स को oid (डिफ़ॉल्ट रूप से) में पढ़ता है, यह JDBC getBytes () का उपयोग करके पढ़ता है, जो PGSQL ड्राइवर डेटा के बजाय 6 बाइट ओड देता है। यह भी ध्यान दें कि प्रश्न के सामने आने के बाद से ब्लॉग लेखक ने सबसे अधिक मदद की है।
जस्टिन

@Justin हालांकि, 3.5 मानचित्रों को हाइबरनेट करने के लिए (डिफ़ॉल्ट रूप से) यह JDBC getBytes () का उपयोग करके पढ़ता है जो PGSQL चालक डेटा के बजाय 6 बाइट ओड लौटाता है - क्या यह तब hibernate.jdbc.use_streams_for_binary=falseभी उपयोग होता है? (स्टीव ने अब क्या कहा यह जांचने के लिए)।
पास्कल थिवेंट

मैं इसे गुण फ़ाइल में निर्दिष्ट करने का प्रयास करने जा रहा हूं, हालांकि PostgreSQLDialect नेInInputStreamToInsertBlob () का गलत उपयोग किया है, इसलिए मैं मानता हूं कि मैं ऐसा हूं - क्योंकि मैं स्पष्ट रूप से इस संपत्ति को स्थापित नहीं कर रहा हूं।
जस्टिन

इस संपत्ति को स्थापित करने के बाद (या तो सही है या गलत), मुझे एक रनटाइम अपवाद मिलता है: ERROR: कॉलम "हस्ताक्षर" प्रकार बाइटा का है, लेकिन अभिव्यक्ति प्रकार ओड का है "। मुझे उल्लेख करना चाहिए कि मैं हाइबरनेट 3.5.5 का उपयोग कर रहा हूं। Final / PG 8.2 ड्राइवर।
जस्टिन

10

यहाँ क्या O'reilly Enterprise JavaBeans, 3.0 कहते हैं

JDBC के पास इन बहुत बड़ी वस्तुओं के लिए विशेष प्रकार हैं। Java.sql.Blob प्रकार बाइनरी डेटा का प्रतिनिधित्व करता है , और java.sql.Clob चरित्र डेटा का प्रतिनिधित्व करता है।

यहाँ PostgreSQLDialect सोर्स कोड जाता है

public PostgreSQLDialect() {
    super();
    ...
    registerColumnType(Types.VARBINARY, "bytea");
    /**
      * Notice it maps java.sql.Types.BLOB as oid
      */
    registerColumnType(Types.BLOB, "oid");
}

तो आप क्या कर सकते हैं

PostgreSQLDialect को इस प्रकार से ओवरराइड करें

public class CustomPostgreSQLDialect extends PostgreSQLDialect {

    public CustomPostgreSQLDialect() {
        super();

        registerColumnType(Types.BLOB, "bytea");
    }
}

अब बस अपनी कस्टम बोली को परिभाषित करें

<property name="hibernate.dialect" value="br.com.ar.dialect.CustomPostgreSQLDialect"/>

और अपने पोर्टेबल JPA @Lob एनोटेशन का उपयोग करें

@Lob
public byte[] getValueBuffer() {

अपडेट करें

यहाँ निकाला गया है यहां

मेरे पास हाइबरनेट 3.3.2 में एक एप्लिकेशन चल रहा है और एप्लिकेशन ठीक काम करता है , ओड (बाइट [जावा में) का उपयोग करते हुए सभी बूँद फ़ील्ड के साथ।

...

3.5 हाइबरनेट करने के लिए माइग्रेट करने से सभी ब्लॉब फ़ील्ड काम नहीं करते हैं , और सर्वर लॉग दिखाता है: ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: कॉलम प्रकार oid का है, लेकिन अभिव्यक्ति bytea

जिसे यहाँ समझाया जा सकता है

यह सामान्यता PG JDBC में बग नहीं है , लेकिन 3.5 संस्करण में हाइबरनेट के डिफ़ॉल्ट कार्यान्वयन में परिवर्तन है । मेरी स्थिति में कनेक्शन पर संगत संपत्ति स्थापित करने से मदद नहीं मिली

...

बहुत अधिक यह जो मैंने 3.5 - बीटा 2 में देखा था, और मुझे नहीं पता कि यह तय किया गया था कि हाइबरनेट है - बिना @ नोट प्रचार के - टाइप ओआईडी का ऑटो-कॉलम बनाएगा, लेकिन इसे बायटिया के रूप में पढ़ने की कोशिश करेगा

दिलचस्प इसलिए है क्योंकि जब वह टाइप करता है। ByBea के रूप में टाइप करें ।BOLB (देखें CustomPostgreSQLDialect) उसे मिलता है

JDBC बैच अपडेट को निष्पादित नहीं कर सका

डालने या अद्यतन करने पर


यह समाधान शानदार लग रहा है, मैं इसे अभी कोशिश कर रहा हूं।
जस्टिन

यह सही DDL उत्पन्न करता है, लेकिन रनटाइम में विफल रहता है: मुझे एक java.sql.BatchUpdateException मिलती है, जब किसी प्रॉपर्टी के साथ ऑब्जेक्ट की कोशिश की जाती है।
जस्टिन

@Justin PostgreSQL के बजाय Oracle का उपयोग करके एक समान परिदृश्य का प्रयास करें और देखें कि आपको क्या मिलता है। बैच अपडेट ऑपरेशन के दौरान होने वाली त्रुटियों के साथ BatchUpdateException को करना पड़ता है।
आर्थर रोनाल्ड

वास्तव में जो मैं वास्तव में चाहता हूं वह BLOB को "bytea" पर मैप करने के लिए नहीं है, बल्कि इसके बजाय Map (बाइट [] + @ लॉब) एनोटेशन संयोजन के लिए Types.VARBARY!
जस्टिन


7

मैं पोस्टग्रेज 9.3 के साथ हाइबरनेट 4.2.7.SP1 का उपयोग कर रहा हूं और मेरे लिए निम्नलिखित कार्य कर रहा हूं:

@Entity
public class ConfigAttribute {
  @Lob
  public byte[] getValueBuffer() {
    return m_valueBuffer;
  }
}

चूंकि ओरेकल को इससे कोई परेशानी नहीं है, और पोस्टग्रेज के लिए मैं कस्टम बोली का उपयोग कर रहा हूं:

public class PostgreSQLDialectCustom extends PostgreSQL82Dialect {

    @Override
    public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
    if (sqlTypeDescriptor.getSqlType() == java.sql.Types.BLOB) {
      return BinaryTypeDescriptor.INSTANCE;
    }
    return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
  }
}

मेरे विचार से इस समाधान का लाभ यह है कि मैं हाइबरनेट जार को अछूता रख सकता हूं।

हाइबरनेट के साथ अधिक पोस्टग्रेज / ओरेकल संगतता मुद्दों के लिए, मेरा ब्लॉग पोस्ट देखें


2
Hibernate 4.3.6 और Postgresql 9.3 का उपयोग करके Postgresql9Dialect के साथ मेरे लिए काम किया। धन्यवाद!
एंड्रेस ओविदो

हाइबरनेट 5.3.7.Final और Postgres95Dialect के साथ काम करता है। Thx
बर्नहार्ड केर्न

6

मुझे आखिरकार यह काम मिल गया है। यह ए। गार्सिया से समाधान पर फैलता है, हालांकि, चूंकि समस्या हाइबरनेट प्रकार में निहित है माल्टोब्लोब प्रकार बस मैपिंग ब्लॉब> बायटिया पर्याप्त नहीं है, हमें मेटेरियलाइज्डब्लोबी टाइप के लिए प्रतिस्थापन की आवश्यकता होती है जो हाइबरनेट टूटे हुए समर्थन का समर्थन करता है। यह कार्यान्वयन केवल बाइटा के साथ काम करता है, लेकिन शायद JIRA मुद्दे से वह व्यक्ति जो OID चाहता था, OID कार्यान्वयन में योगदान दे सकता है।

उदासी से इन प्रकारों को रनटाइम पर बदलना एक दर्द है, क्योंकि उन्हें बोली का हिस्सा होना चाहिए। यदि केवल इस JIRA वृद्धि 3.6 में हो जाता है तो यह संभव होगा।

public class PostgresqlMateralizedBlobType extends AbstractSingleColumnStandardBasicType<byte[]> {
 public static final PostgresqlMateralizedBlobType INSTANCE = new PostgresqlMateralizedBlobType();

 public PostgresqlMateralizedBlobType() {
  super( PostgresqlBlobTypeDescriptor.INSTANCE, PrimitiveByteArrayTypeDescriptor.INSTANCE );
 }

  public String getName() {
   return "materialized_blob";
  }
}

इसका ज्यादातर हिस्सा स्थिर हो सकता है (getBinder () को वास्तव में एक नए उदाहरण की आवश्यकता है?), लेकिन मैं वास्तव में हाइबरनेट आंतरिक को नहीं समझता हूं, इसलिए यह ज्यादातर कॉपी + पेस्ट + संशोधित है।

public class PostgresqlBlobTypeDescriptor extends BlobTypeDescriptor implements SqlTypeDescriptor {
  public static final BlobTypeDescriptor INSTANCE = new PostgresqlBlobTypeDescriptor();

  public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
   return new PostgresqlBlobBinder<X>(javaTypeDescriptor, this);
  }
  public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
   return new BasicExtractor<X>( javaTypeDescriptor, this ) {
    protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { 
      return (X)rs.getBytes(name);
    }
   };
  }
}

public class PostgresqlBlobBinder<J> implements ValueBinder<J> {
 private final JavaTypeDescriptor<J> javaDescriptor;
 private final SqlTypeDescriptor sqlDescriptor;

 public PostgresqlBlobBinder(JavaTypeDescriptor<J> javaDescriptor, SqlTypeDescriptor sqlDescriptor) { 
  this.javaDescriptor = javaDescriptor; this.sqlDescriptor = sqlDescriptor;
 }  
 ...
 public final void bind(PreparedStatement st, J value, int index, WrapperOptions options) 
 throws SQLException {
  st.setBytes(index, (byte[])value);
 }
}

आपके शोध के लिए +1। बधाई हो। बस एक सलाह: अपने प्रश्न / उत्तर को 8 बार तक संपादित करने को प्राथमिकता दें। अन्यथा, आपका प्रश्न / उत्तर सामुदायिक विकि बन जाएगा और आप प्रतिष्ठा प्राप्त नहीं करेंगे और यूपी वोट की गणना अब नहीं की जाएगी
आर्थर रोनाल्ड

जीते हैं और सीखते हैं कि मुझे लगता है, मेरे पास बहुत सारे संपादन थे, क्योंकि मैं अपने परीक्षण वातावरण के साथ एक चीज या अन्य करना भूल गया था।
जस्टिन

यहां भी, अनुसंधान के लिए +1 और आपकी स्थिति के लिए एक समाधान है।
पास्कल थिवेंट

4.2.x हाइबरनेट संस्करण के साथ समाधान के लिए कोई मौका? हाइबरनेट इंटर्नस थोड़ा बदल गया है (मैंने टिप्पणी की गई समस्या की पुष्टि की: hibernate.atlassian.net/browse/HHH-5584 )।
पीटर बुटकोविक

2

मैंने @Lob के एनोटेशन को जोड़कर मेरा मुद्दा तय किया है जो अलंकृत में बाइट [] को बूँद के रूप में बनाएगा, लेकिन यह एनोटेशन फ़ील्ड को ओड के रूप में बनाएगा जो ठीक से काम नहीं करता है, बाइट बनाने के लिए [] बाइट के रूप में बनाया गया है जिसे मैंने ग्राहक के लिए बोली के रूप में बनाया है। नीचे के रूप में पोस्टग्रेट करता है

Public class PostgreSQLDialectCustom extends PostgreSQL82Dialect {
    public PostgreSQLDialectCustom() {
        System.out.println("Init PostgreSQLDialectCustom");
        registerColumnType( Types.BLOB, "bytea" );

      }

    @Override
    public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
    if (sqlTypeDescriptor.getSqlType() == java.sql.Types.BLOB) {
      return BinaryTypeDescriptor.INSTANCE;
    }
    return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
  }
 }

साथ ही बोली के लिए पैरामीटर को ओवरराइड करना होगा

spring.jpa.properties.hibernate.dialect = com.ntg.common.DBCompatibilityHelper.PostgreSQLDialectCustom

अधिक संकेत उसे मिल सकते हैं: https://dzone.com/articles/postgres-and-oracle


0

मैंने इसे पोस्टग्रेज के लिए एक्सएमएल फ़ाइल के साथ एनोटेशन ओवरराइड करके काम किया। Oracle के लिए एनोटेशन रखा गया है। मेरी राय में, इस मामले में यह सबसे अच्छा होगा कि हम इस परेशानी की मैपिंग को ओवरराइड करें- xml मैपिंग के साथ कुछ एनीटी। हम xml मानचित्रण के साथ एकल / एकाधिक संस्थाओं को ओवरराइड कर सकते हैं। इसलिए हम अपने मुख्य रूप से समर्थित डेटाबेस के लिए एनोटेशन और एक दूसरे डेटाबेस के लिए xml फ़ाइल का उपयोग करेंगे।

नोट: हमें केवल एक एकल वर्ग को ओवरराइड करने की आवश्यकता है, इसलिए यह कोई बड़ी बात नहीं है। एक्सएमएल के साथ एनोटेशन को ओवरराइड करने के लिए मेरे उदाहरण उदाहरण से अधिक पढ़ें


0

Postgres पर @ लोब बाइट के लिए टूट रहा है [] क्योंकि यह इसे ओड के रूप में बचाने की कोशिश करता है, और स्ट्रिंग के लिए भी यही समस्या होती है। नीचे कोड पोस्टग्रेज पर टूट रहा है जो ओरेकल पर ठीक काम कर रहा है।

@Lob
private String stringField;

तथा

@Lob
private byte[]   someByteStream;

पोस्टग्रेज पर ऊपर तय करने के लिए नीचे कस्टम hibernate.dialect लिखा है

public class PostgreSQLDialectCustom extends PostgreSQL82Dialect{

public PostgreSQLDialectCustom()
{
    super();
    registerColumnType(Types.BLOB, "bytea");
}

 @Override
 public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
    if (Types.CLOB == sqlTypeDescriptor.getSqlType()) {
      return LongVarcharTypeDescriptor.INSTANCE;
    }
    return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
  }
}

अब कस्टम बोली को हाइबरनेट में कॉन्फ़िगर करें

hibernate.dialect=X.Y.Z.PostgreSQLDialectCustom   

XYZ पैकेज नाम है।

अब यह ठीक काम कर रहा है। नोट- मेरा हाइबरनेट संस्करण - 5.2.8.Final पोस्टग्रैज संस्करण- 9.6.3 है


0

धन्यवाद जस्टिन, पास्कल मुझे सही दिशा के लिए मार्गदर्शन करने के लिए। मैं हाइबरनेट 3.5.3 के साथ भी इसी मुद्दे का सामना कर रहा था। आपके शोध और सही वर्गों की ओर संकेत करने से मुझे इस मुद्दे की पहचान करने और एक सुधार करने में मदद मिली।

उन लोगों के लिए लाभ के लिए जो अभी भी हाइबरनेट 3.5 के साथ अटके हुए हैं और ओड + बाइट [] + @ बीएलबी संयोजन का उपयोग कर रहे हैं, निम्नलिखित है कि मैंने समस्या को ठीक करने के लिए क्या किया है।

  1. मैंने एक कस्टम ब्लॉबटाइप बनाया जो कि MaterializedBlobType का विस्तार कर रहा है और सेट को ओवरराइड कर रहा है और ओई स्टाइल एक्सेस के साथ तरीके प्राप्त करता है।

    public class CustomBlobType extends MaterializedBlobType {
    
    private static final String POSTGRESQL_DIALECT = PostgreSQLDialect.class.getName();
    
    /**
     * Currently set dialect.
     */
    private String dialect = hibernateConfiguration.getProperty(Environment.DIALECT);
    
    /*
     * (non-Javadoc)
     * @see org.hibernate.type.AbstractBynaryType#set(java.sql.PreparedStatement, java.lang.Object, int)
     */
    @Override
    public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
        byte[] internalValue = toInternalFormat(value);
    
        if (POSTGRESQL_DIALECT.equals(dialect)) {
            try {
    
    //I had access to sessionFactory through a custom sessionFactory wrapper.
    st.setBlob(index, Hibernate.createBlob(internalValue, sessionFactory.getCurrentSession()));
                } catch (SystemException e) {
                    throw new HibernateException(e);
                }
            } else {
                st.setBytes(index, internalValue);
            }
        }
    
    /*
     * (non-Javadoc)
     * @see org.hibernate.type.AbstractBynaryType#get(java.sql.ResultSet, java.lang.String)
     */
    @Override
    public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
        Blob blob = rs.getBlob(name);
        if (rs.wasNull()) {
            return null;
        }
        int length = (int) blob.length();
        return toExternalFormat(blob.getBytes(1, length));
      }
    }
    1. हाइबरनेट के साथ CustomBlobType रजिस्टर करें। निम्नलिखित है कि मैं क्या हासिल किया है कि

      hibernateConfiguration= new AnnotationConfiguration();
      Mappings mappings = hibernateConfiguration.createMappings();
      mappings.addTypeDef("materialized_blob", "x.y.z.BlobType", null);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.