Oracle's JDBC's getBytes глючит?
От: Pan-Halt Украина coming soon
Дата: 13.04.05 08:55
Оценка:
Всем привет.

Случилась у меня проблема, на которую я в инете ответа не нашел.
Надеюсь что тут подскажут где искать.

Суть проблемы в том, что ResultSet.getBytes и ResultSet.getBinaryStream возсращают разный контент ! (getBytes — неправельный, getBinaryStream — правельный)

У меня стабильно не работает на:
Oracle 10g
Oracle's thin JDBC driver for JDK 1.4
JDK 1.4.2_06

Проверочный код ниже.
Акцент на методы getAsBytes и getAsStream.

package dbSelect;

import java.io.*;
import java.sql.*;
import java.awt.*;

public class FromOracle {
    private static Connection createConnection() throws ClassNotFoundException, SQLException {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        return DriverManager.getConnection("jdbc:oracle:thin:@172.25.8.30:1521:ORCL", "system", "password");
    }

    private static void createAndFillTable() throws SQLException, ClassNotFoundException, IOException {
        Connection connection = createConnection();
        try {
            connection.createStatement().execute("drop table test1");
        } catch (SQLException e) {
            // ignore if table doesn't exist
        }

        connection.createStatement().execute("create table test1 (attribute blob)");

        PreparedStatement preparedStatement = connection.prepareStatement("insert into test1 (attribute) values (?)");
        preparedStatement.setBytes( 1, toByteArray(new Point(12,34)) );
        preparedStatement.execute();

        connection.close();
    }

    private static byte[] getAsBytes() throws SQLException, ClassNotFoundException {
        Connection connection = createConnection();

        try {
            ResultSet resultSet = connection.createStatement().executeQuery("select attribute from test1");
            resultSet.next();
            return resultSet.getBytes(1);
        } finally {
            connection.close();
        }
    }

    private static byte[] getAsStream() throws SQLException, ClassNotFoundException, IOException {
        Connection connection = createConnection();

        try {
            ResultSet resultSet = connection.createStatement().executeQuery("select attribute from test1");
            resultSet.next();
            InputStream binaryStream = resultSet.getBinaryStream(1);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            copyStreamContent(binaryStream, baos);
            return baos.toByteArray();
        } finally {
            connection.close();
        }
    }

    public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException {
        createAndFillTable();

        byte[] resultAdBytes = getAsBytes();
        byte[] resultAsStream = getAsStream();

        System.out.println("resultAdBytes.length = " + resultAdBytes.length);
        System.out.println("resultAsStream.length = " + resultAsStream.length);
        System.out.println("resultAdBytes:");
        printByteArray(resultAdBytes);
        System.out.println("resultAsStream:");
        printByteArray(resultAsStream);

        System.out.println("fromByteArray(resultAsStream) = " + fromByteArray(resultAsStream));
        System.out.println("fromByteArray(resultAdBytes) = " + fromByteArray(resultAdBytes));
        /*

java.io.StreamCorruptedException: invalid stream header
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:737)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:253)
    . . .

        */
    }

    public static void printByteArray(byte[] array) {
        for (int i = 0; i < array.length; i++)
            System.out.print(array[i] + " ");
        System.out.println();
    }

    public static Object fromByteArray(byte[] buf) throws IOException, ClassNotFoundException {
      final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buf);
      final ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
      final Object result = objectInputStream.readObject();
      objectInputStream.close();
      return result;
    }

    public static byte[] toByteArray(Object original) throws IOException {
      final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
      final ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
      objectOutputStream.writeObject(original);
      objectOutputStream.close();
      byte[] buf = byteArrayOutputStream.toByteArray();
      return buf;
    }

    public static void copyStreamContent(InputStream inputStream, OutputStream outputStream) throws IOException {
      final byte[] buffer = new byte[10 * 1024];
      int count;
      while ((count = inputStream.read(buffer)) > 0)
        outputStream.write(buffer, 0, count);
    }
}


результат на экране:
resultAdBytes.length = 86

resultAsStream.length = 51

resultAdBytes:
0 84 0 1 1 12 0 0 0 1 0 0 0 1 0 0 0 2 110 -87 0 0 -49 -13 0 0 -49 -14 0 1 0 1 0 0 0 1 -84
-19 0 5 115 114 0 14 106 97 118 97 0 0 119 116 0 43 111 -31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 -49 -14 0 64 -36 -86 0 0 

resultAsStream:
-84 -19 0 5 115 114 0 14 106 97 118 97 46 97 119 116 46 80 111 105 110 116 -74 -60 -118 114
52 126 -56 38 2 0 2 73 0 1 120 73 0 1 121 120 112 0 0 0 12 0 0 0 34 

fromByteArray(resultAsStream) = java.awt.Point[x=12,y=34]

java.io.StreamCorruptedException: invalid stream header
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:737)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:253)
    at dbSelect.FromOracle.fromByteArray(FromOracle.java:95)
    at dbSelect.FromOracle.main(FromOracle.java:77)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:324)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:86)
Exception in thread "main"


Первые четыре байта должны быть "-84 -19 0 5", а вот в resultAdBytes — не так

Подскажите, спецы.
Re: Oracle's JDBC's getBytes глючит?
От: investigator Россия  
Дата: 13.04.05 09:14
Оценка:
Здравствуйте, Pan-Halt, Вы писали:

PH> ... skipped ...


Не спец в оракловском JDBC, но когда у нас возникла похожая проблема с чтением блобов, следующий подход помог:

ResultSet rs = ...;
rs.getBlob(index).getBytes(1, (int)rs.getBlob(index).length());
Re[2]: Oracle's JDBC's getBytes глючит?
От: Pan-Halt Украина coming soon
Дата: 13.04.05 09:20
Оценка:
Здравствуйте, investigator, Вы писали:

PH>> ... skipped ...


I>Не спец в оракловском JDBC, но когда у нас возникла похожая проблема с чтением блобов, следующий подход помог:


I>
I>ResultSet rs = ...;
I>rs.getBlob(index).getBytes(1, (int)rs.getBlob(index).length());
I>


Ты прав. Такой подход работает.
Но есть одно но: вызываю getBytes не я, а hibernate... Поэтому хочеться разобраться что тут не так, а уж после hbernate карячить.
Re[3]: Oracle's JDBC's getBytes глючит?
От: Аноним  
Дата: 13.04.05 09:28
Оценка:
Здравствуйте, Pan-Halt, Вы писали:

PH>Здравствуйте, investigator, Вы писали:


PH>>> ... skipped ...


I>>Не спец в оракловском JDBC, но когда у нас возникла похожая проблема с чтением блобов, следующий подход помог:


I>>
I>>ResultSet rs = ...;
I>>rs.getBlob(index).getBytes(1, (int)rs.getBlob(index).length());
I>>


PH>Ты прав. Такой подход работает.

PH>Но есть одно но: вызываю getBytes не я, а hibernate... Поэтому хочеться разобраться что тут не так, а уж после hbernate карячить.
Если получится хибернат раскорячить под ораклиные блобы сообщите плз о результатах
Спасибо.
Re[4]: Oracle's JDBC's getBytes глючит?
От: Pan-Halt Украина coming soon
Дата: 13.04.05 09:48
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Если получится хибернат раскорячить под ораклиные блобы сообщите плз о результатах

А>Спасибо.

Возможно, Вам поможет флажок "hibernate.jdbc.use_streams_for_binary" — "Use streams when writing/reading binary or serializable types to/from JDBC".

При установке в true хибертейтовский BinaryType читает данные через потоки.

А какая в Вас проблема?
Re[4]: Oracle's JDBC's getBytes глючит?
От: Pan-Halt Украина coming soon
Дата: 13.04.05 09:51
Оценка:
Здравствуйте, Аноним, Вы писали:

I>>>Не спец в оракловском JDBC, но когда у нас возникла похожая проблема с чтением блобов, следующий подход помог:


I>>>
I>>>ResultSet rs = ...;
I>>>rs.getBlob(index).getBytes(1, (int)rs.getBlob(index).length());
I>>>


PH>>Ты прав. Такой подход работает.

PH>>Но есть одно но: вызываю getBytes не я, а hibernate... Поэтому хочеться разобраться что тут не так, а уж после hbernate карячить.
А>Если получится хибернат раскорячить под ораклиные блобы сообщите плз о результатах
А>Спасибо.


Собсвенно, скорее всего Вам поможет подмена get и set методов в хибернейтовском BinaryType на то, что предложил investigator.
Но я такой подход не пробывал и за корректность не ручаюсь.
Re[5]: Oracle's JDBC's getBytes глючит?
От: zalexaka  
Дата: 13.04.05 10:01
Оценка:
Здравствуйте, Pan-Halt, Вы писали:

PH>Возможно, Вам поможет флажок "hibernate.jdbc.use_streams_for_binary" — "Use streams when writing/reading binary or serializable types to/from JDBC".


PH>При установке в true хибертейтовский BinaryType читает данные через потоки.


PH>А какая в Вас проблема?


в наст. момент мапинг блобов не произвожу, а делаю а в лоб через нибернатовский Connection (пока устраивает)
по поводу мапинга нашёл статейку может кому пригодиться
Ещё раз спасибо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.