Database Support
This article provides an overview of the database engines and persistence providers we support out-of-the-box and also run automated tests against.
Overview
We consider four different scenario's for each combination of a database engine and persistence provider. These scenario's depend on how the identifier for a DataElement is generated.
- Using native database sequences.
- Using an identity column. This is our recommended default at this time.
- Deprecated No options are specified. Without specifying a specific strategy, you will let the persistence provider choose, which could be subject to change.
- Deprecated Using the global sequence option. This was introduced for OpenJPA to mimic the behavior of Hibernate 4.
Persistence providers
At this time, we support three different persistence providers out of the box.
- Hibernate 5: Our recommended default for Java EE based applications.
- Hibernate 6: Our recommended default for Jakarta EE based applications.
- OpenJPA: While supported, we do not recommend using OpenJPA, as it is not as well supported as Hibernate in general.
While we do not officially support it, our applications are known to also operate using EclipseLink. If targeted in an application, it may require additional work to deploy using this technology.
We support Hibernate 6 to target Jakarta EE, but we are currently still working on integrating it into our automated testing process. As such, it is not yet listed in the databases section of this post. At the moment we assume that what works with Hibernate 5 will likely also work with Hibernate 6.
There was a breaking change in the legacy default identity generation change, but our expanders resolve this by forcing it to follow the same strategy as Hibernate 5. This ensures existing databases do not have to be migrated when updating to Jakarta EE.
Databases
Out of the box we support a broad range of databases. In theory any JPA compatible SQL database engine should work, but the database engines listed below are the ones we actively test for. Our recommended default is Postgresql.
- ❌ Unsupported combination.
- 👍 Should work and is tested daily.
- 🔥 We were not able to get this operational and should ideally be avoided.
Each combination may include additional notes.
Postgresql
| HIBERNATE5 | OPENJPA | |
|---|---|---|
| 1. SEQUENCE | 👍 | 👍 |
| 2. IDENTITY | 👍 | 👍1 |
| 3. LEGACY | 👍 | 👍2 |
| 4. GLOBALSEQ | ❌ | 👍 |
-
1 OpenJPA tries to execute
SELECT pg_get_serial_sequence($1, $2)on the database frequently, which fails. The database returnsrelation "elementTableName" does not exist. This does however not seem to impede the operation of the application, but does log many errors on the database server. -
2 By default OpenJPA uses sequence tables, rather than native sequences.
HSQLDB
Historically we used to run HSQL databases in-memory. While we still support HSQLDB today, we no longer operate it in-memory. We provide our own HSQLDB docker image to run it in server mode, which is also used in our regression tests.
| HIBERNATE5 | OPENJPA | |
|---|---|---|
| 1. SEQUENCE | 👍 | 👍1 |
| 2. IDENTITY | 👍 | 👍 |
| 3. LEGACY | 👍 | 👍 |
| 4. GLOBALSEQ | ❌ | 👍 |
- 1 OpenJPA dislikes sequences being defined with the same name in the JPA annotations, though it does not break on this.
Microsoft SQL Server
| HIBERNATE5 | OPENJPA | |
|---|---|---|
| 1. SEQUENCE | 👍 | 🔥2 |
| 2. IDENTITY | 👍1 | 🔥3 |
| 3. LEGACY | ❌ | ❌ |
| 4. GLOBALSEQ | ❌ | 🔥2 |
-
1 The
sql-expandersgenerate id fields using the typeBIGINT, which was introduced in SQL Server 2008. The expanders currently target the older default dialect for SQL Server, which usesNUMERIC(19)as type. -
2 The dictionary for SQL Server in OpenJPA does not support sequences, even though sequence support was introduced in SQL Server 2012. It should be possible to define the command to select the next sequence value in
persistence.xml, as a property of the dictionary. E.g.:<property name="openjpa.jdbc.DBDictionary" value="sqlserver(NextSequenceQuery="SELECT NEXT VALUE FOR NS_SEQUENCE")"/> -
3 Only works correctly if OpenJPA is allowed to populate the schemas with tables. OpenJPA throws exceptions (
gen-nofktablein OpenJPA codebase) when the database has been populated with thesql-expanders, because the OpenJPASchemaGeneratorcan't find a tables involved with foreign keys.
Additional notes
-
SQL Server does not support
DROP ... CASCADEand as such all constraints, tables and schemas have to be dropped individually. It is possible to use procedures in Transact-SQL to do this, but thesql-expandersdo not generate any cleaning statements because of this. If not in use, it is however possible to drop an entire database in one query. -
Applications must be expanded using the ApplicationInstanceOption
db.schema.enableEscapeTableNameto avoid issues with theaccountcomponents, asUseris a reserved word in SQL Server. -
Because Microsoft dropped support for TLSv1, there might be some issues when trying to connect to the database and you have not added appropriate certificates to the certificate store of the application server/flyway jvm.
cautionFor development, a quick workaround is to trust any server by default by adding
;trustServerCertificate=trueto the JDBC urls of both Flyway and the TomEE data sources. Avoid using this in production environments!
Mysql
| HIBERNATE5 | OPENJPA | |
|---|---|---|
| 1. SEQUENCE | 🔥1 | 🔥1 |
| 2. IDENTITY | 🔥1 | 🔥1 |
| 3. LEGACY | ❌ | ❌ |
| 4. GLOBALSEQ | ❌ | ❌ |
- 1 Mysql does not allow the direct use of a table in a
SELECT-query if that query is part of theWHERE-clause of anUPDATE-query on that same table. This can only be achieved using multi-table update statements in Mysql. Theworkflow.DataAccesselement has a custom query defined which violates this requirement. It is likely that individual components which do not violate this requirement can be deployed with an individual connection to a Mysql server. More information: https://dev.mysql.com/doc/refman/8.0/en/update.html
Mariadb
| HIBERNATE5 | OPENJPA | |
|---|---|---|
| 1. SEQUENCE | 👍1 | 🔥2,3 |
| 2. IDENTITY | 👍 | 🔥2,4 |
| 3. LEGACY | ❌ | ❌ |
| 4. GLOBALSEQ | ❌ | ❌ |
-
1 The expanders currently target the older default dialect for MariaDB, which is equivalent to MariaDB 8.2. Sequences generated by Hibernate for this dialect use tables, whereas since MariaDB 10.3 there is support for native sequences. For now the
sql-expandersalso provider the table sequence structure. -
2 The database dialect for MariaDB in OpenJPA uses rather old Mysql typing for fields, such as
BITinstead ofBOOLEAN. -
3 Unlike Hibernate 5, OpenJPA does not provide an alternative implementation for the
SEQUENCEstrategy if it doesn't think the database supports sequences. The dictionary for MariaDB in OpenJPA does not support sequences, even though sequence support was introduced in MariaDB 10.3. It should be possible to define the command to select the next sequence value inpersistence.xml, as a property of the dictionary. E.g.:<property name="openjpa.jdbc.DBDictionary" value="mariadb(NextSequenceQuery="NEXTVAL(NS_SEQUENCE)=""/> -
4 OpenJPA does not select the correct database, even with the
catalogfield present on the@Tableannotations.
Oracle Database
| HIBERNATE5 | OPENJPA | |
|---|---|---|
| 1. SEQUENCE | 👍 | 🔥1 |
| 2. IDENTITY | 👍 | 🔥1 |
| 3. LEGACY | ❌ | ❌ |
| 4. GLOBALSEQ | ❌ | ❌ |
- 1 OpenJPA fails to detect existing foreign keys correctly and attempts to recreate them, resulting in duplicate constraint errors.
Additional notes
- Applications must be expanded using the ApplicationInstanceOption
db.schema.enableEscapeTableNameto avoid issues with theaccountcomponents, asUseris a reserved word in Oracle databases.