JDBC codecs for the two Postgres types the domain refuses to know about.
The point of both is negative: no org.postgresql.util.PGobject and no java.sql.Array ever escapes this module. A repository returns io.circe.Json, which is the same type modules/kernel already speaks, so the jsonb-ness of the storage stops at the edge of persistence and swapping Magnum out (ADR §12.4 budgets for it) does not ripple into the domain.
Written as setObject(pos, text, Types.OTHER) rather than by constructing a PGobject: with OTHER the driver sends the value as an unknown-typed literal, which Postgres then coerces to whatever the target column or cast requires. That keeps the codec driver-shaped rather than pgjdbc-class-shaped, and it is why callers can write ?::jsonb for a comparison and a bare ? for an insert into a jsonb column.
Reading goes through getString, so what comes back is Postgres's canonical jsonb rendering — key order, insignificant whitespace and duplicate keys are already gone by then. That is a property of the storage decision (ADR §12.4), not of this codec: payload_sha256 exists precisely because jsonb cannot promise byte-identity.
text[], for the = ANY(?) and tags @> ? filter cases.
text[], for the = ANY(?) and tags @> ? filter cases.
Summoned explicitly rather than imported as a given. -Wunused:all + -Werror has known false positives on given-imports that are only consumed inside Magnum's sql macro (ADR §12.4), and naming the instances here means there is no import to be wrongly flagged and no ambiguity about which array element type is in play.
Callers must cast the placeholder — ?::text[] — because the driver names the element type VARCHAR, and text[] @> varchar[] is not a resolvable operator. The cast also pins one plan-cache entry for a filter whose list length varies, which is the whole reason ADR §6.2 binds these lists as a single array parameter instead of an IN (?, ?, …).
Written as setObject(pos, text, Types.OTHER) rather than by constructing a PGobject: with OTHER the driver sends the value as an unknown-typed literal, which Postgres then coerces to whatever the target column or cast requires. That keeps the codec driver-shaped rather than pgjdbc-class-shaped, and it is why callers can write ?::jsonb for a comparison and a bare ? for an insert into a jsonb column.
Reading goes through getString, so what comes back is Postgres's canonical jsonb rendering — key order, insignificant whitespace and duplicate keys are already gone by then. That is a property of the storage decision (ADR §12.4), not of this codec: payload_sha256 exists precisely because jsonb cannot promise byte-identity.