2011-11-21 11 views
9

तो entity.getHistory() अशक्त निम्नलिखित कोड का टुकड़ा है:PostgreSQL JDBC अशक्त स्ट्रिंग एक bytea के रूप में लिया

(getEntityManager() रिटर्न वसंत इंजेक्शन EntityManager, डाटाबेस क्षेत्र इतिहास प्रकार है: किसी पाठ या varchar2 (2000)

Query query = getEntityManager().createNativeQuery("insert into table_name(..., history, ....) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 
[...] 
.setParameter(6, entity.getHistory()) 
[...] 

query.executeUpdate(); 

देता है अजीब अपवाद:

17/11/11 06:26:09:009 [pool-2-thread-1] WARN util.JDBCExceptionReporter:100 - SQL Error: 0, SQLState: 42804 
17/11/11 06:26:09:009 [pool-2-thread-1] ERROR util.JDBCExceptionReporter:101 - ERROR: **column "history" is of type text but expression is of type bytea** 

संकेत: आप को फिर से लिखने या अभिव्यक्ति कास्ट करने के लिए की आवश्यकता होगी


ओएस: CentOS रिलीज 5.6 (अंतिम)
जावा: 1.6.0_26
डीबी: PostgreSQL 8.1
JDBC ड्राइवर: PostgreSQL-9.1-901.jdbc4
अनुप्रयोग सर्वर: अपाचे

समस्या केवल इस विन्यास में हुई -टॉमकैट-6.0.28

सबकुछ कुछ अन्य कॉन्फ़िगरेशन या जब इतिहास खाली स्ट्रिंग पर ठीक काम कर रहा है। pgAdmin से निष्पादित वही कथन ठीक काम करता है।

मुझे लगता है कि समस्या PostgreSQL जेडीबीसी ड्राइवर में है, क्या शून्य कार्य के रूप में शून्य स्ट्रिंग का इलाज करने के लिए कुछ समझदार कारण है? शायद पोस्टग्रेस 8 और 9 के बीच कुछ अजीब बदलाव?

+0

मुझे एंटिटी मैनेजर को संदेह होगा कि गलत मूल्यों के लिए गलत 'PreparedStatement.setXXX() 'विधि को कॉल किया जाए। आप 8.1 जेडीबीसी ड्राइवर भी कोशिश कर सकते हैं। बीटीडब्ल्यू: क्या आप जानते हैं कि 8.1 अब समर्थित नहीं है? –

+0

क्या आप अपने पहले दो अनुच्छेदों को स्पष्ट कर सकते हैं? वे समझ में नहीं आता है। –

+0

पोस्टग्रेएसक्यूएल 9 + (@a_horse_with_no_name क्लाइंट के पास 8.1 होना चाहिए ...), विंडोज 7 इत्यादि के साथ ठीक कोड काम कर रहा है। अगर इकाई है .getHistory() शून्य के बजाय यह काम कर रहा है। PgAdmin से निष्पादित वही डालने ठीक काम करता है। – laidlook

उत्तर

1

आप क्वेरी के बजाय PreparedStatement वर्ग का उपयोग करने के लिए तैयार हैं:

if (entity.getHistory() == null) 
    stmt.setNull(6, Types.VARCHAR); 
else 
    stmt.setString(6, entity.getHistory()); 

(यह है कि आपके क्वेरी स्ट्रिंग में ?::text का उपयोग कर भी काम करेगा संभव है, लेकिन मैं इसे इस तरह से अपने आप को कभी नहीं किया है।)

4

चूंकि आप शून्य मूल्य के साथ setParameter(int,Object) पर कॉल कर रहे हैं, अनुमान लगाते हैं कि इकाई प्रबंधक को पता नहीं है कि पैरामीटर को बांधने के लिए किस दृढ़ता प्रकार का उपयोग करना है। Istr Hibernate SerializableType का उपयोग करने के लिए एक पूर्वाग्रह है, जो एक बाइटा के बराबर होगा।

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

4

उन्हें आसानी से ठीक नहीं है (IMHO यह है अपने बस EntityManager के देशी-एसक्यूएल क्वेरी इंटरफ़ेस कोस आवेषण ऐसा करने के लिए, बजाय वास्तव में इकाई मानचित्रण, या बस JDBC के माध्यम से छोड़ने के लिए डेसर्ट): जब आप कर रहे हैं क्वेरी स्ट्रिंग का निर्माण, यदि कोई पैरामीटर शून्य होने वाला है - "?" के बजाय "null" का उपयोग करें।

जैसा कि @ाराqnid कहते हैं, हाइबरनेट गलत तरीके से शून्य प्रकारों को कास्टा में कास्टिंग कर रहा है क्योंकि यह किसी भी बेहतर नहीं जानता है।

0

एसडीएल प्रकार पैरामीटर के साथ जेडीबीसी सेट नल विरासत जेडीबीसी ड्राइवरों के लिए फॉलबैक है जो जेडीबीसी चालक परीक्षण सूट पास नहीं करते हैं।

लेखक की ओर से एक है, जहां एक का चयन करें: इस प्रकार

एक क्वेरी के भीतर अशक्त त्रुटियों से बचाव कर सकते हैं lastName शून्य या उससे पहले (a.lastName) है =: lastName

इस के बाद Postgresql में काम करना चाहिए इस issue का फिक्स।

0

का उपयोग हाइबरनेट विशिष्ट सत्र एपीआई एक समाधान के रूप में काम करता है:

String sql = "INSERT INTO person (id, name) VALUES (:id, :name)"; 
Session session = em.unwrap(Session.class); 
SQLQuery insert = session.createSQLQuery(sql); 
sql.setInteger("id", 123); 
sql.setString("name", null); 
insert.executeUpdate(); 

मैं भी HHH-9165 दायर किया है तो इस मामले की रिपोर्ट करने के लिए, अगर यह वास्तव में एक बग है।

+0

नोट मुझे यह समस्या 'शॉर्ट' के साथ थी और वहां आप 'setShort() 'का उपयोग नहीं कर सकते क्योंकि यह एक गैर-शून्य' छोटा 'लेता है। हाइबरनेट 4.x के साथ समाधान करना है: 'setParameter ("short", ShortValue, ShortType.INSTANCE); '(3.x के साथ मुझे लगता है कि यह 'शॉर्टटाइप' का उपयोग करने के बजाय 'हाइबरनेट .HORT' है)। –

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