[java] org.h2.jdbc.JdbcSQLException: Hexadecimal string with odd
number of characters: 0 [90003-44]
[java] at org.h2.message.Message.getSQLException(Message.java:
65)
[java] at org.h2.message.Message.getSQLException(Message.java:
47)
[java] at
org.h2.util.ByteUtils.convertStringToBytes(ByteUtils.java:52)
[java] at org.h2.value.Value.convertTo(Value.java:480)
[java] at org.h2.command.dml.Insert.update(Insert.java:78)
[java] at
org.h2.command.CommandContainer.update(CommandContainer.java:64)
[java] at org.h2.command.Command.executeUpdate(Command.java:
120)
[java] at
org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:
127)
[java] at
org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:
116)
Thanks,
Mark
This exception occurs if the database tries to convert a VARCHAR to a
BINARY data type, and the value is not a correct representation. For
example, X'00aabb' is correct (0x00, 0xaa, 0xbb), or even 'FACE'
(0xfa, 0xce). But '010' is incorrect (two characters per byte are
required). I hope you understand what I am trying to say...
Thomas
Thanks for the information. I don't believe I'm trying to do anything
illegal here. The code and error follows. Am I doing anything wrong?
Thanks,
Mark
import java.sql.*;
public class TestDB {
public static void main(String args[]) throws Exception {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:./
testDB", "", "");
conn.setAutoCommit(true);
Statement st = conn.createStatement();
st.executeUpdate("DROP TABLE IF EXISTS test_object_table");
st.executeUpdate("CREATE TABLE IF NOT EXISTS test_object_table
(id INTEGER NOT NULL, object0 JAVA_OBJECT NOT NULL, PRIMARY
KEY(id))");
PreparedStatement ps = conn.prepareStatement("INSERT INTO
test_object_table values(?, ?)");
ps.setInt(1, 1);
ps.setObject(2, new Integer(3));
ps.executeUpdate();
ResultSet rs = st.executeQuery("select * from
test_object_table");
while (rs.next()) {
int id = rs.getInt("id");
int object0 = (Integer) rs.getObject("object0");
System.out.println("id = " + id + ", object0 = " +
object0);
}
rs.close();
conn.close();
}
}
The error message:
[arai:/tmp] melmerp> java -cp "`cygpath -wp .:/usr/local/h2/bin/
h2.jar`" TestDB
Exception in thread "main" org.h2.jdbc.JdbcSQLException: Hexadecimal
string with odd number of characters: 3 [90003-44]
at org.h2.message.Message.getSQLException(Message.java:65)
at org.h2.message.Message.getSQLException(Message.java:47)
at org.h2.util.ByteUtils.convertStringToBytes(ByteUtils.java:
52)
at org.h2.value.Value.convertTo(Value.java:480)
at org.h2.command.dml.Insert.update(Insert.java:78)
at
org.h2.command.CommandContainer.update(CommandContainer.java:64)
at org.h2.command.Command.executeUpdate(Command.java:120)
at
org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:
127)
at
org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:
116)
at TestDB.main(TestDB.java:16)
On Apr 9, 9:38 pm, "Thomas Mueller" <thomas.tom.muel...@gmail.com>
wrote:
> Hi,
>
> This exception occurs if the database tries to convert a VARCHAR to a
> BINARY data type, and the value is not a correct representation. For
> example, X'00aabb' is correct (0x00, 0xaa, 0xbb), or even 'FACE'
> (0xfa, 0xce). But '010' is incorrect (two characters per byte are
> required). I hope you understand what I am trying to say...
>
> Thomas
>
ps.setObject(2, new Integer(3), Types.JAVA_OBJECT);
works instead of
ps.setObject(2, new Integer(3));
Can anyone explain why? The second statement works in mckoi db. Is one
wrong versus the other or is there room for interpretation in the jdbc
spec?
Thanks,
Mark
The problem is that the JDBC driver of H2 doesn't 'know' it should
convert the Integer object to the JAVA_OBJECT type (probably McKoi
'knows' this). Therefore the JDBC driver of H2 converts it to an
INTEGER (because the object is an instance of java.lang.Integer).
Later, the database (not the driver any more) tries to convert the
integer 3 to a JAVA_OBJECT (by first converting it to a VARCHAR, and
then trying to interpret the characters as a list of bytes). If you
tell the H2 JDBC driver that the object is JAVA_OBJECT, it will
convert it correctly (that is, serialize it). I think ps.setObject(2,
new Integer(3), Types.JAVA_OBJECT) is more portable (more databases
understand it), but I didn't test it yet with other database.
Thomas