The H2 Backend — Peculiarities¶
H2 supports the H2 database engine (2.x), embedded, in-memory or
in server mode. H2 is the backend Tentackle's own tests run on (see
tentackle-test-pdo), and it is the natural
choice for an application's unit tests as well. This document collects what deviates from the other backends,
PostgreSQL in particular.
The backend is selected by a JDBC URL containing
:h2:(org.h2.Driver). There is no version check.
Type Mapping¶
SqlType |
H2 type | Note |
|---|---|---|
VARCHAR(n) |
VARCHAR(n) |
n is capped at 1048576 (getMaxSize) |
VARCHAR |
VARCHAR(1048576) |
an attribute without a size gets the maximum size |
CHAR |
CHAR(1) |
|
CLOB |
CLOB |
|
XML |
CLOB |
H2 backs its SQLXML implementation by a CLOB, hence isSqlxmlSupported() is true |
JSON |
JSON |
native, see below |
BLOB |
BLOB |
|
BIT |
BOOLEAN |
|
TINYINT |
TINYINT |
|
FLOAT |
REAL |
DOUBLE is declared as DOUBLE PRECISION |
DECIMAL |
DECIMAL(19) |
without a size, see below; the maximum precision is 99999 |
UUID |
UUID |
native; UUID is therefore a reserved word |
Decimals¶
An unsized DECIMAL needs a precision. A bare DECIMAL is DECIMAL(100000,0) in H2 and would silently
round away every fraction digit, so getDefaultSize supplies 19 — the same remedy the MySQL backend applies
(see Decimals). As there, only PostgreSQL, Oracle and SAP HANA keep the scale of a decimal
column the model declares no size for.
JSON¶
H2 has a native JSON type, but it parses only bytes as a document: a Java string would be stored as a JSON
string value. setJson therefore binds the UTF-8 bytes, which H2 validates on the way in. H2 reports a JSON
column as Types.OTHER with the type name JSON, which the type-name-aware jdbcTypeToSqlType overload uses to
tell it from a UUID column. Like PostgreSQL's jsonb, H2 drops insignificant whitespace from the stored
document.
Queries¶
- Paging and locking follow the SQL standard, not PostgreSQL's order:
buildSelectSqlemitsOFFSET ? ROWS FETCH FIRST ? ROWS ONLY FOR UPDATE. H2 rejects any other order as a syntax error, which is why the trailing parameters are bound offset-first. - Sequences are read with
SELECT NEXTVAL('name'). - Array parameters are supported with the
ANYandALLoperators. - Sub-selects need an alias (
isAliasRequiredForSubSelect()).
Schema and Migration¶
- Names may be up to 256 characters long.
information_schemais a reserved schema, whilepublic— H2's default schema — remains a legal schema name. - Comments are created with
COMMENT ONfor tables, columns, indexes and sequences. - Column alterations change the type, the null constraint and the default in separate statements
(
ALTER COLUMN ... TYPE,SET/DROP NOT NULL,SET DEFAULT). DROP ... IF EXISTSis supported (seesetDropIfExistsEnabled).- No filtered and no function-based indexes: the model is refused for H2 if it uses them, unless the index is marked optional, in which case it is skipped (see Index Lines).
- An unsized
VARCHARcolumn is not migrated again. H2 reports it with the size it was created with (or as unbounded), which the migrator recognizes as the maximum size.
Runtime¶
- In-memory databases.
isDatabaseInMemory()returnstruefor a URL containing:mem:. The test base classes use it to decide whether the schema must be created before the tests run. - Transient errors. Besides the standard SQLState
40001, the states50200(lock timeout) and90131(concurrent update) mark a transaction as worth retrying. - XA is supported via
org.h2.jdbcx.JdbcDataSource(see JTA/XA). - The backend id is H2's session id (
SESSION_ID()).
Related Documentation¶
- Tentackle SQL — the backend abstraction this backend implements.
- The PostgreSQL Backend — the reference backend H2 is most often compared with.
- tentackle-test-pdo — the test support running on H2.
- Tentackle SQL Maven Plugin — generates the DDL and the migration scripts.