2010-05-12 9 views
7

के साथ स्प्रिंग के कीहोल्डर का उपयोग करके मैं एक तालिका में डालने के लिए स्प्रिंग के नामांकित पैरामीटर जेडीबीसी टेम्पलेट का उपयोग कर रहा हूं। प्राथमिक कुंजी प्राप्त करने के लिए तालिका अनुक्रम पर एक NEXTVAL का उपयोग करती है। मैं चाहता हूं कि यह जेनरेट आईडी मुझे वापस पास कर दे। मैं इस तरह वसंत के keyholder कार्यान्वयन उपयोग कर रहा हूँ:प्रोग्रामेटिक रूप से जेनरेट की गई प्राथमिक कुंजी

KeyHolder key = new GeneratedKeyHolder(); 
jdbcTemplate.update(Constants.INSERT_ORDER_STATEMENT, params, key); 

हालांकि, जब मैं इस बयान चलाने के लिए, मैं हो रही है:

org.springframework.dao.DataRetrievalFailureException: The generated key is not of a supported numeric type. Unable to cast [oracle.sql.ROWID] to [java.lang.Number] 
    at org.springframework.jdbc.support.GeneratedKeyHolder.getKey(GeneratedKeyHolder.java:73) 

कोई भी विचार है कि मैं क्या याद आ रही है?

उत्तर

-3

मुझे लगता है कि आप JdbcTemplate पर गलत विधि का उपयोग कर रहे हैं। update तरीकों कि अपने कोड खंड से मेल खाती प्रतीत होता है की केवल एक ही

int update(String sql, Object... args) 

यदि हां, तो आप एक दो तत्व vargs सरणी के रूप में params और key गुजर रहे है, और JdbcTemplate एक सामान्य बाँध के रूप में key इलाज है पैरामीटर, और गलत व्याख्यान।

कि एक KeyHolder लेता JdbcTemplate पर केवल सार्वजनिक update विधि

int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder) 

तो आपको लगता है कि उपयोग करने के लिए अपने कोड अलग तरीके से व्यक्त करने की आवश्यकता होगी है। Oracle के साथ आप (NamedParameterJdbcOperations से) अन्य विधि का उपयोग करने की जरूरत है - -

+2

भ्रामक, Konstantin –

2

आपको JdbcTemplate.update(PreparedStatementCreator p, KeyHolder k) निष्पादित करना होगा।

डेटाबेस से लौटाई गई कुंजी KeyHolder पैरामीटर ऑब्जेक्ट में इंजेक्शन दी जाएगी।

एक उदाहरण:

final String INSERT_ORDER_STATEMENT 
     = "insert into order (product_id, quantity) values(?, ?)"; 

KeyHolder keyHolder = new GeneratedKeyHolder(); 
    jdbcTemplate.update(new PreparedStatementCreator() { 
     public PreparedStatement createPreparedStatement(
      Connection connection) throws SQLException { 
       PreparedStatement ps = connection.prepareStatement(
        INSERT_ORDER_STATEMENT, new String[] { "id" }); 
       ps.setInt(1, order.getProductId()); 
       ps.setInt(2, order.getQuantity()); 
       return ps; 
      } 
     }, keyHolder); 

अधिक जानकारी संदर्भ दस्तावेज में here पाया जा सकता है।

+0

यह वास्तव में धारक में ROWID लौटा रहा है और संख्या नहीं! – supernova

15

बस एक समान समस्या हल हो जाती

int update(String sql, 
      SqlParameterSource paramSource, 
      KeyHolder generatedKeyHolder, 
      String[] keyColumnNames) 
      throws DataAccessException 
स्वत: जनरेट वाले कॉलम keyColumnNames साथ

, मेरे मामले सिर्फ [ "आईडी"] में। अन्यथा आपको जो भी मिलता है वह ROWID है। विवरण के लिए Spring doc देखें।

+1

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

+0

ओरेकल $ uck नहीं है? लेकिन यह सही जवाब है –

0

@ कोंस्टेंटिन उत्तर पर कोई विस्तृत जानकारी नहीं: यहां एक पूरी तरह से काम कर रहा उदाहरण है: मान लीजिए डाटाबेस ओरेकल और कॉलम नाम है जो स्टोर जेनरेट आईडी है "GENERATED_ID" (कोई नाम हो सकता है)। नोट: मैंने नामांकित पैरामीटर JdbcTemplate.update (....) इस उदाहरण में वसंत के JdbcTemplate वर्ग नहीं।

 public Integer insertRecordReturnGeneratedId(final MyObject obj) 
      { 
      final String INSERT_QUERY = "INSERT INTO MY_TABLE VALUES(GENERATED_ID_SEQ.NEXTVAL, :param1, :param2)"; 
      try 
       { 
        MapSqlParameterSource parameters = new MapSqlParameterSource().addValue("param1", obj.getField1()).addValue("param2", obj.getField1()) ; 
        final KeyHolder holder = new GeneratedKeyHolder(); 
        this.namedParameterJdbcTemplate.update(INSERT_QUERY, parameters, holder, new String[] {"GENERATED_ID" }); 
        Number generatedId = holder.getKey(); 
        // Note: USING holder.getKey("GENERATED_ID") IS ok TOO. 
        return generatedId.intValue(); 
       } 
       catch(DataAccessException dataAccessException) 
       { 
     } 
     } 
संबंधित मुद्दे