2010-06-29 24 views
40

पहचान नहीं है मैं देशी पोस्टजीआईएस क्वेरी निष्पादित करने के लिए हाइबरनेट/जेपीए का उपयोग कर रहा हूं। इन प्रश्नों के साथ समस्या यह है कि उन्हें ऐसे पैरामीटर की आवश्यकता है जो शास्त्रीय एक्स = 'मान' फ़ॉर्म के नहीं हैं।जेपीए/हाइबरनेट मूल क्वेरी पैरामीटर

उदाहरण के लिए, निम्नलिखित लाइनों दुर्घटना

String queryString = "select * from Cell c where ST_DWithin(c.shape, SetSRID(ST_GeomFromEWKT('POINT(:lon :lat)'),4326), 0.1)"; 
    Query query = Cell.em().createNativeQuery(queryString, Cell.class); 
    query.setParameter("lon", longitude); 
    query.setParameter("lat", latitude); 

play.exceptions.JavaExecutionException: org.hibernate.QueryParameterException: could not locate named parameter [lon] 
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:259) 
at Invocation.HTTP Request(Play!) 
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryParameterException: could not locate named parameter [lon] 
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:358) 

निम्न क्वेरी हालांकि काम करता है:

String queryString = String.format("select * from Cell c where ST_DWithin(c.shape, SetSRID(ST_GeomFromEWKT('POINT(%f %f)'),4326), 0.1)", longitude, latitude); 
Query query = Cell.em().createNativeQuery(queryString, Cell.class); 

(लेकिन यह एसक्यूएल इंजेक्शन की आशंका वाले ... है)

किसी को भी करता है इस मामले में setParameter() का उपयोग कैसे करें?

उत्तर

17

शायद तुम इस तरह से मानकों को लगातार तार के बाहर हैं और क्वेरी पार्सर द्वारा मान्यता प्राप्त होना चाहिए

'POINT(' || :lon || ' ' || :lat || ')' 

साथ

'POINT(:lon :lat)' 

बदल सकते हैं।

+0

Waoo ... धन्यवाद! यह काम करने लगता है !!! – user99054

+3

+1 दिलचस्प चाल जो वास्तव में समस्या की पुष्टि करती है उद्धरणों से आती है, नामित पैरामीटर से नहीं (जिसे किसी को जेपीए से बचना चाहिए)। –

+0

NamedNativeQuery एनोटेशन के साथ स्प्रिंग डेटा में काम करता है, इसलिए रिपोजिटरी कार्यान्वयन के निर्माण की आवश्यकता नहीं है। Spec उद्धृत करने और मुझे याद दिलाने के लिए – lreeder

77

नामित पैरामीटर का उपयोग देशी प्रश्नों के लिए परिभाषित नहीं किया गया है। जेपीए विनिर्देश (अनुभाग 3.6.3 नामांकित पैरामीटर) से:

नाम मापदंडों पहचानकर्ता धारा 4.4.1 में परिभाषित के लिए नियमों का पालन करें। नामित पैरामीटर का उपयोग जावा पर्सिस्टेंस क्वेरी भाषा, पर लागू होता है और मूल क्वेरी के लिए परिभाषित नहीं किया जाता है। केवल स्थितित्मक पैरामीटर बाध्यकारी पोर्टेबल देशी क्वेरी के लिए उपयोग किया जा सकता है।

बजाय निम्न प्रयास करें:

String queryString = "select * from Cell c where ST_DWithin(c.shape, SetSRID(ST_GeomFromEWKT('POINT(?1 ?2)'),4326), 0.1)"; 
Query query = Cell.em().createNativeQuery(queryString, Cell.class); 
query.setParameter(1, longitude); 
query.setParameter(2, latitude); 

ध्यान दें कि जेपीए> = 2.0 में आप देशी प्रश्नों में नामित पैरामीटर का उपयोग कर सकते हैं।

+4

+1 यह पोर्टेबल नहीं है। मैंने वास्तव में हाइबरनेट परियोजना में मूल प्रश्नों में नामित पैरामीटर का उपयोग किया है, जो ठीक काम कर रहा है। एक और पुरानी परियोजना में, जरूरी जरूरी चीजों के आधार पर, सभी मूल प्रश्न स्थितित्मक मानकों का उपयोग करते हैं, इसलिए मुझे इसे पहले और भूल जाना चाहिए :) –

+0

हाय, आपके उत्तर के लिए धन्यवाद। हालांकि, यह अभी भी सेट पैरामीटर (1, रेखांश) org.hibernate.QueryParameterException: घोषित ordinal पैरामीटर की संख्या से परे स्थिति पर क्रैश प्रतीत होता है। याद रखें कि क्रमिक पैरामीटर 1-आधारित हैं! स्थिति: 1 कोई विचार? – user99054

+1

@ सैमोक: मुझे आश्चर्य है कि POINT के आसपास एकल उद्धरण यहां समस्या नहीं है। –

2

तो, विचारों को पहचानने के लिए पोस्टग्रेस को मजबूर करने के लिए जोर्न होर्स्टमान द्वारा सुझाए गए कॉन्सटेनेशन चाल का उपयोग करना था। निम्नलिखित कोड काम करता है:

String queryString = "select * from Cell c where ST_DWithin(c.shape, SetSRID(ST_GeomFromEWKT('POINT(' || :lon || ' ' || :lat || ')'),4326), 0.2)"; 
Query query = Cell.em().createNativeQuery(queryString, Cell.class); 
query.setParameter("lon", longitude); 
query.setParameter("lat", latitude); 

आपके उत्तरों के लिए बहुत बहुत धन्यवाद!

+1

असल में, यह पोस्टग्रेज़ नहीं है जो पैरामीटर को पहचान नहीं रहा था, लेकिन आपका जेपीए प्रदाता (एकल उद्धरण के कारण)। –

2

तुम भी

ST_Point(:lon,:lat) 

साथ पूरे

ST_GeomFromEWKT('POINT(' || :lon || ' ' || :lat || ')') 

कॉल और इसे बदलना से छुटकारा पा सकते तो फिर तुम उद्धरण के बारे में चिंता करने की जरूरत नहीं है।

2

पास्कल का जवाब सही है, लेकिन ... आपका समाधान एसक्यूएल इंजेक्शन प्रवण कैसे है? यदि आप अपने उदाहरण में String.format और पैरामीटर प्रकार %f का उपयोग कर रहे हैं तो नंबर से कुछ और भी java.util.IllegalFormatConversionException फेंकता है। "Xxx 'या 1 = 1 -" जैसी कोई संभावित पास मान नहीं है।

सावधान रहें, %sString.format में एसक्यूएल इंजेक्शन तैयार है।

4

मुझे एक ही समस्या थी और पाया कि पैरामीटर देशी प्रश्नों में प्रश्न चिह्नों के साथ सेट किए जा सकते हैं। इसे आज़माएं:

String queryString = "select * from Cell c where ST_DWithin(c.shape, SetSRID(ST_GeomFromEWKT('POINT(? ?)'),4326), 0.1)"; 

Query query = Cell.em().createNativeQuery(queryString, Cell.class); 
query.setParameter(1, longitude); 
query.setParameter(2, latitude); 
2

मुझे इसी तरह के मुद्दे का सामना करना पड़ा। मैं भंडार में देशी क्वेरी का उपयोग कर रहा था? 1। इसने इसे निम्न जैसे ब्रैकेट के आसपास पैरामीटर के आस-पास हल किया।

SELECT * FROM XYZ WHERE ABC = (?1) 

http://javageneralist.blogspot.com/2011/06/jpa-style-positional-param-was-not.html

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