Testing my DAL with H2 in-memory database currently doesn\'t work because the data tye BINARY gets converted to VARBINARY:
CREATE TABLE test (
pk_user_id I
which results in a wrong data type
No, not the wrong type, just another label for the same type.
The binary type has five synonyms: { BINARY | VARBINARY | LONGVARBINARY | RAW | BYTEA }
All five names mean the same type, and all map to byte[]
in Java.
Data types are not strictly defined in the SQL world. The SQL spec defines only a few types. Many database systems define many types by many names. To make it easier for a customer to port from one database system to theirs, the database vendors commonly implement synonyms for data types to match those of their competitors where the types are compatible.
H2 like many other databases systems have more than one name for a datatype. For a binary type where the entire value is loaded into memory, H2 defines five names for the same single data type:
{ BINARY | VARBINARY | LONGVARBINARY | RAW | BYTEA }
Similarly, H2 provides for a signed 32-bit integer datatype by any of five synonyms:
{ INT | INTEGER | MEDIUMINT | INT4 | SIGNED }
So you can specify any of these five names but you will get the same effect, the same underlying datatype provided by H2.
Indeed, I myself ran code to create the column using each of those five names for the binary type. In each case, the metadata for the column name reports the datatype as VARBINARY
.
While it does not really matter which of the five is used internally to track the column’s datatype, I am a bit surprised as to the use of VARBINARY
because the H2 datatype documentation page heading advertises this type as BINARY
. So I would expect BINARY
to be used by default in the metadata. You might want to log a bug/issue for this if you really care, as it seems either the doc heading should be changed to VARBINARY
or H2’s internal labelling for the datatype should be changed to BINARY
.
Below is some example Java JDBC code confirming the behavior you report in your Question.
I suggest you change your datatype-checking code to look for any of the five possible names for this datatype rather than check for only one specific name.
try {
Class.forName ( "org.h2.Driver" );
} catch ( ClassNotFoundException e ) {
e.printStackTrace ( );
}
try ( Connection conn = DriverManager.getConnection ( "jdbc:h2:mem:" ) ;
Statement stmt = conn.createStatement ( ) ; ) {
String tableName = "test_";
String sql = "CREATE TABLE " + tableName + " (\n" +
" pk_user_id_ INT AUTO_INCREMENT(1, 1) PRIMARY KEY,\n" +
" uuid_ BINARY(16) UNIQUE NOT NULL\n" +
");";
// String sql = "CREATE TABLE " + tableName +
// "(" +
// " id_ INT AUTO_INCREMENT(1, 1) PRIMARY KEY, " +
// " binary_id_ BINARY(16) UNIQUE NOT NULL, " +
// " uuid_id_ UUID, " +
// " age_ INTEGER " + ")";
stmt.execute ( sql );
// List tables
DatabaseMetaData md = conn.getMetaData ( );
try ( ResultSet rs = md.getTables ( null, null, null, null ) ) {
while ( rs.next ( ) ) {
System.out.println ( rs.getString ( 3 ) );
}
}
// List columns of our table.
try ( ResultSet rs = md.getColumns ( null, null, tableName.toUpperCase ( Locale.US ), null ) ) {
System.out.println ( "Columns of table: " + tableName );
while ( rs.next ( ) ) {
System.out.println ( rs.getString ( 4 ) + " | " + rs.getString ( 5 ) + " | " + rs.getString ( 6 ) ); // COLUMN_NAME, DATA_TYPE , TYPE_NAME.
}
}
} catch ( SQLException e ) {
e.printStackTrace ( );
}
CATALOGS
COLLATIONS
…
USERS
VIEWS
TEST_
Columns of table: test_
PK_USER_ID_ | 4 | INTEGER
UUID_ | -3 | VARBINARY
Tips:
uuid
could conflict with H2’s UUID
datatype.uuid BINARY(16)
suggests you are trying to store a UUID (a 128-bit value where some bits have defined semantics). Note that H2 supports UUID natively as a data type as does Postgres and some other database systems. So change uuid_ BINARY(16)
to uuid_ UUID
.