2012-09-07 2 views
0

У меня есть файл csv, загруженный пользователем, который мне нужно хранить как Clob, в таблице oracle.сохранение InputStream как clob в oracle с помощью jdbc

Поэтому у меня есть этот код:

MultipartHttpServletRequest mr = (MultipartHttpServletRequest) ctx.getRequest(); 
    final MultipartFile f = mr.getFile("datafile"); 
    final InputStream is = f.getInputStream(); 
    ... 
    jdbc.getJdbcOperations().execute(sql, new PreparedStatementCallback<Integer>() { 
    public Integer doInPreparedStatement(final PreparedStatement psInsert) throws SQLException, 
          DataAccessException { 
    ... 
    psInsert.setCharacterStream(1, new InputStreamReader(is)); 
    psInsert.executeUpdate(); 
    } 
}); 

Кроме того, я попытался с помощью методов setClob и setAsciiStream из PreparedStatement, а также я попытался this подход (настройка размера файла), но результат тот же -

java.lang.AbstractMethodError 
    org.apache.commons.dbcp.DelegatingPreparedStatement.setAsciiStream(DelegatingPreparedStatement.java:338) 
    org.apache.commons.dbcp.DelegatingPreparedStatement.setAsciiStream(DelegatingPreparedStatement.java:338) 
    org.apache.commons.dbcp.DelegatingPreparedStatement.setAsciiStream(DelegatingPreparedStatement.java:338) 

основная InputStream является ByteArrayInputStream (если это может сделать какой-либо разницы)

PS: табл е действительно имеет поле CLOB:

P_FILE CLOB NOT NULL, 

UPD: Я на самом деле не пробовал Oracle реализованы методы. Он работает, единственная проблема заключается в том, что драйвер oracle реализует не все методы, сравнимые с теми, которые находятся в интерфейсе PreparedStatement. Класс смотреть на возможных доступных методов OraclePreparedStatement ...

+0

вы пробовали setcharacterstream? http://stackoverflow.com/a/5067581/706695 – HRgiger

+0

@HRgiger Да, я использую setCharacterStream - это то, что на самом деле в моем вопросе. Единственное отличие с ответом, с которым вы связались - я использую не StringReader, а InputStreamReader. Я мог бы читать все до строки, а затем создавать StreamReader (это на самом деле работает!) - но это просто беспорядочное решение. – javagirl

+0

im not sure если я правильно понимаю, но clob для ввода текста. если вы хотите использовать байтовый ввод blob. в случае, если входной поток на самом деле текстовый, возможно, попробуйте его прочитать в строку и записать это в db. вы можете сделать setString работать с clob btw. –

ответ

1

От AbstractMethodError javadoc:

Брошенный, когда приложение пытается вызвать абстрактный метод. Обычно эта ошибка улавливается компилятором; эта ошибка может возникнуть только при запуске времени, если определение какого-либо класса несовместимо изменилось с Последний компилятор в настоящее время компилируется.

Проверьте, чтобы все ваши классы были текущими. Я бы сделал чистую и восстановил весь ваш проект. Кроме того, убедитесь, что ваши классы времени компиляции и времени выполнения эквивалентны (в отношении версий библиотек и т. Д.)

+0

@GriffeyDoc все компилируется успешно, но когда у вас есть приложение с пружиной, с бобами, загружаемыми через ApplicationContext, и когда фактические объекты, такие как Connection, скрыты под связкой Wrappers - это становится сложным. Этот случай с DelegatingPreparedStatement - это тот – javagirl

0

позволяет легко читать/писать любые типы с помощью TypeTranslator. См. Пакет org.sormula.examples.blob в проекте. Код будет похож на CLOB.

public class WidgetTanslator1 implements TypeTranslator<Widget> 
{ 
    public void write(PreparedStatement preparedStatement, int parameterIndex, Widget parameter) throws Exception 
    { 
     // convert from domain object to bytes 
     ByteArrayOutputStream bos = new ByteArrayOutputStream(1000); 
     try (ObjectOutputStream oos = new ObjectOutputStream(bos)) 
     { 
      oos.writeObject(parameter); 

      // convert bytes to jdbc blob 
      preparedStatement.setBlob(parameterIndex, new SerialBlob(bos.toByteArray())); 
     } 
    } 


    public Widget read(ResultSet resultSet, int parameterIndex) throws Exception 
    { 
     // convert from jdbc blob to bytes to domain object 
     Blob blob = resultSet.getBlob(parameterIndex); 
     try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(blob.getBytes(1, (int)blob.length())))) 
     { 
      return (Widget)ois.readObject(); 
     } 
    } 
} 

Annotate CLOB поле, как это:

@ImplicitType(translator=WidgetTanslator1.class) 
Widget widget; 
Смежные вопросы