Closed nscuro closed 2 weeks ago
The easier alternative is to move all API server tests to use PostgreSQL testcontainers instead of H2. Has the nice side effect that we can ban H2 from the project alltogether.
PR to make this happen: https://github.com/DependencyTrack/hyades-apiserver/pull/573
Raised https://github.com/datanucleus/datanucleus-rdbms/issues/494.
Not really sure what areas of DataNucleus will need to be touched, so hoping the maintainer can nudge me in the right direction.
Turns out this can be solved with extensions:
@Persistent
@Column(name = "DATA", jdbcType = "CLOB")
@Extensions({
@Extension(vendorName = "datanucleus", key = "insert-function", value = "(?::JSONB)"),
@Extension(vendorName = "datanucleus", key = "update-function", value = "(?::JSONB)")
})
private String data;
No implementation necessary for this one, see comment above.
PostgreSQL's
JSONB
columns are more efficient to store, faster to query, and can be indexed.DataNucleus does not support
JSONB
type per default.We can map Java objects to JSON strings using custom
AttributeConverter
s, but when inserting the resulting strings, Postgres yields a type error, e.g.:With raw SQL, this could be addressed using explicit casting, like this:
But with DataNucleus we don't get to make this customization.
Transmitting
JSONB
through raw JDBC can be achieved usingPGobject
:To get this level of control with DataNucleus, it seems like we have to build a DataNucleus extension, which provides a
ColumnMapping
, as per https://www.datanucleus.org/products/accessplatform/extensions/extensions.html#rdbms_datastore_mappingI made some progress using the extension way, but got stuck when trying to also make it work with H2, which is still being used in some tests.
Fields annotated with
@Column
must then include thesqlType = "JSONB"
qualifier for theColumnMapper
to be picked up:This works fine when using Postgres, but fails in tests where DataNucleus auto-generates the schema for an in-memory H2 database:
The root cause being that H2 doesn't have a
JSONB
type.