2010-09-21 10 views
7

Tengo el código JDBC que se inserta en una tabla de base de datos mediante la ejecución de un PreparedStatement. Cuando ejecuto el código en una base de datos HSQLDB en memoria (como parte de una prueba JUnit) obtengo una SQLFeatureNotSupportedException con la única información que es el mensaje "feature not supported" y el código de proveedor -1500. Lo que estoy haciendo es una inserción básica en una tabla. No puedo imaginar que esto no esté soportado en la última HSQLDB.HSQLDB mensaje de excepción críptica: "característica no compatible"

Mi código:

public Observations saveOrUpdate(final Observations observations) 
{ 
    try 
    { 
     if (connection == null) 
     { 
      connection = getJdbcTemplate().getDataSource().getConnection(); 
     } 

     // create the prepared statement 
     String sql = "INSERT INTO " + Observations.TABLE_NAME + 
        " (OBS_YEAR, WINTER, SPRING, SUMMER, FALL, ANNUAL, DATA_TYPE, CREATED_DATE, UPDATED_DATE, " + 
        Observations.ID_COLUMN_NAME + 
        ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; 
     PreparedStatement preparedStatement = connection.prepareStatement(sql); 
     preparedStatement.setInt(1, observations.getYear()); 
     preparedStatement.setBigDecimal(2, observations.getJan()); 
     preparedStatement.setBigDecimal(3, observations.getFeb()); 
     preparedStatement.setBigDecimal(4, observations.getMar()); 
     preparedStatement.setBigDecimal(5, observations.getApr()); 
     preparedStatement.setBigDecimal(6, observations.getMay()); 
     preparedStatement.setString(7, observations.getDataType().toString()); 
     preparedStatement.setTimestamp(8, new Timestamp(observations.getCreatedDate().getTime())); 
     preparedStatement.setTimestamp(9, new Timestamp(observations.getUpdatedDate().getTime())); 
     preparedStatement.setLong(10, observations.getId()); 
     preparedStatement.executeUpdate(sql); 

     return observations; 
    } 
    catch (SQLException ex) 
    { 
     throw new RuntimeException(ex); 
    } 
} 

Puede alguien sugerir qué puede ser el problema o algo más que debería investigar más a fondo? Gracias de antemano por tu ayuda.

--James

+1

tratar de publicar más información: registro de la excepción, la versión de su HSQLDB (2.0 tal vez), la versión de Java, etc. Estoy buscando en Para ayudarte Supongo que es un problema de compatibilidad entre el jre y su hsqldb. – Aito

+0

Muchas gracias, Aito. Estoy usando el archivo HSQLDB 2.0 JAR. Estoy ejecutando el código como parte de una prueba JUnit 4. Lo lanzo desde Eclise IDE que está usando un 1.6 JRE. El DataSource se configura con Spring y recibo la conexión de Spring JdbcTemplate que he configurado en la clase DAO que contiene este código. –

Respuesta

10

Debe llamar al preparedStatement.executeUpdate() (sin el parámetro sql).

Ha llamado al método PreparedStatement.executeUpdate(String sql), que es ilegal según la especificación JDBC. Realmente no tiene sentido pasar la instrucción SQL nuevamente, porque ya la pasó cuando creó el objeto PreparedStatement. Incluso aunque haya pasado la misma cadena, no es legal llamar a este método. Es un poco extraño que llamar a un método no sea legal :-) pero así son las cosas. Todos los controladores JDBC estándar conformes deben lanzar una excepción en este caso.

Pero acepto que el mensaje de error es críptico.

+0

Bingo, eres el ganador. ¡Muchas gracias! –

-1

cuestiones sistémicas con HSQLDB son a menudo debido a los desajustes en el servidor frente a la versión del controlador (cualquier desajuste en absoluto no funcionará en mi experiencia).

Sospecho en su mayoría que no es su problema. Como dijo que el archivo db está "en memoria", supongo que el controlador & del servidor es el mismo archivo .jar. Pero en caso de que mi suposición sea incorrecta, pensé en tirar esto por ahí.

+0

Porque esto es especulación, ¿no debería ser un comentario a la pregunta y no una respuesta? –

+0

@Jacob Tomaw, ¿o sí? Nunca he visto una directriz como esa. Y lo que es más, ¿el 98% de las respuestas a las preguntas sobre este sitio no se especula en algún nivel? Si la persona que pregunta conociera suficientes detalles acerca de su problema como para que no hubiera necesidad de especulación para encontrar la causa, ¿no habría sido capaz de encontrar la respuesta él mismo? –

+0

Willis Su especulación es que su respuesta no es útil. Para mí, sería más útil hacer la pregunta que aclarará el problema para usted y que el solicitante sabrá la respuesta a "Cuando dice que esto es una base de datos 'en memoria', quiere decir que esa base de datos y la prueba son corriendo en la misma JVM? " como un comentario. Una vez que se responde esa pregunta, puede proporcionar una respuesta informada. –

1

Alguna información adicional que encontré en http://hsqldb.org/doc/changelog_1_7_2.txt:

The execute(String sql), executeUpdate(String sql) and executeQuery(String sql) 
commands are no-longer supported for PreparedStatements according to JDBC specs. 
Use an ordinary Statement for calling these methods. 
Cuestiones relacionadas