[java] org.h2.jdbc.JdbcSQLException: Hexadecimal string with odd number of characters: 0 [90003-44]

8,713 views
Skip to first unread message

mel...@gmail.com

unread,
Apr 9, 2007, 4:15:18 AM4/9/07
to H2 Database

I'm wondering if anyone has any idea of what causes this error:

[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

Thomas Mueller

unread,
Apr 10, 2007, 12:38:54 AM4/10/07
to h2-da...@googlegroups.com
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

mel...@gmail.com

unread,
Apr 10, 2007, 4:34:27 AM4/10/07
to H2 Database
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
>

mel...@gmail.com

unread,
Apr 10, 2007, 4:53:37 AM4/10/07
to H2 Database
I was playing with my code and figured out that:

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

Thomas Mueller

unread,
Apr 11, 2007, 8:35:47 PM4/11/07
to h2-da...@googlegroups.com
Hi,

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

Reply all
Reply to author
Forward
0 new messages