SimpleJdbcCall ignora la dimensione di recupero di JdbcTemplate

Stiamo chiamando la procedura pl / sql memorizzata tramite Spring SimpleJdbcCall, il set fetchsize su JdbcTemplate viene ignorato da SimpleJdbcCall. La dimensione del recupero dei risultati del rowmapper è impostata su 10 anche se abbiamo impostato il file jdbctemplate fetchsize su 200. Qualche idea del perché questo accada e come risolverlo?

Ho stampato il set di risultati di resultset nel rowmapper nello snippet di codice seguente: una volta che è 200 e altre volte è 10 anche se uso lo stesso JdbcTemplate in entrambe le occasioni.

Questa esecuzione diretta tramite jdbctemplate restituisce il recupero di 200 nel mappatore di riga

jdbcTemplate = new JdbcTemplate(ds); jdbcTemplate.setResultsMapCaseInsensitive(true); jdbcTemplate.setFetchSize(200); List temp = jdbcTemplate.query("select 1 from dual", new ParameterizedRowMapper() { public Object mapRow(ResultSet resultSet, int i) throws SQLException { System.out.println("Direct template : " + resultSet.getFetchSize()); return new String(resultSet.getString(1)); } }); 

Questa esecuzione tramite SimpleJdbcCall restituisce sempre il recupero di 10 nel rowmapper

 jdbcCall = new SimpleJdbcCall(jdbcTemplate).withSchemaName(schemaName) .withCatalogName(catalogName).withProcedureName(functionName); jdbcCall.returningResultSet((String) outItValues.next(), new ParameterizedRowMapper<Map>() { public Map mapRow(ResultSet rs, int row) throws SQLException { System.out.println("Through simplejdbccall " + rs.getFetchSize()); return extractRS(rs, row); } }); outputList = (List<Map>) jdbcCall.executeObject(List.class, inParam); 

Non sono sicuro di quanto sia getFetchSize() metodo getFetchSize() su ResultSet . JdbcTemplate chiama setFetchSize() JdbcTemplate e presuppone che il driver JDBC faccia la cosa giusta con esso, inclusa la propagazione a tutti gli oggetti ResultSet . Sembra che il driver JDBC Oracle non sia, in questo caso.

La ragione per cui si ottiene un comportamento diverso dai due approcci è che l’esecuzione di una semplice SELECT tramite JdbcTemplate è semplice JDBC, mentre il ResultSet si ottiene da SimpleJdbcCall viene ottenuto come parametro OUT alla chiamata. Quest’ultimo è più complesso e sembra che l’informazione sia andata persa.

Come soluzione alternativa, hai provato a chiamare ResultSet.setFetchSize() tu stesso? Potrebbe non funzionare, ma vale la pena provarlo. Puoi anche inviare un problema a http://jira.springsource.org/ per vedere se pensano che il livello JDBC di Spring possa indirizzarlo in modo trasparente.

Se si desidera limitare il numero di righe restituite con Oracle, è necessario utilizzare una query di sottoselezione e specificare il rownumber di inizio e fine in questo modo:

 SELECT * FROM (SELECT ROWNUM as id, demo.* FROM DEMO_TABLE demo) WHERE id >= startRowNumber AND id <= stopRowNumber; 

Se non vuoi alcun codice specifico di Oracle, dovresti considerare JPA invece di JDBC:

 Query selectQuery = entityManager.createQuery(queryString); selectQuery.setMaxResults(maxNumberOfElements); selectQuery.setFirstResult(startRowNumber); List demoList = entityManager.getResultList(queryString); 

Non una risposta diretta, ma una cosa utile, penso. Quando si creano oggetti di classi primaverili a mano, la maggior parte delle persone tende a dimenticare di chiamare il metodo afterPropertiesSet () (che viene chiamato da Spring per eseguire qualsiasi inizializzazione).

Ho controllato jdbcTemplate.afterPropertiesSet () sembra solo impostare il traduttore delle eccezioni e l’origine dei dati.