Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017ic4b6Kg9RWSTJzyz6KP9X
4.9 KiB
json-columns
Companion module for the ankurm.com article JSON Columns in Hibernate 7: @JdbcTypeCode(SqlTypes.JSON) and Querying JSONB on PostgreSQL
(https://ankurm.com/hibernate-json-column-jdbctypecode-jsonb-postgresql/).
Every claim in the article comes from a test or script here; each writes what it observed to output/.
The tests run against a real PostgreSQL 18 and a real MySQL 8.0 server started without Docker (see Quickstart).
Versions
| Component | Version | Notes |
|---|---|---|
| Hibernate ORM | 7.4.14.Final |
newest 7.x GA on Maven Central on 2026-10-30; overrides the 7.4.13.Final Spring Boot 4.1.2 manages |
| Spring Boot | 4.1.2 |
parent POM; Spring Data JPA 4.1.2 |
| Jackson | 3.1.7 (tools.jackson) |
what Boot 4.1.2 manages; Jackson 2 2.22.4 only in the jackson2 profile |
| PostgreSQL / driver | 18.6 / 42.7.14 |
embedded-postgres-binaries-linux-amd64 18.6.0 from Maven Central, no Docker |
| MySQL / driver | 8.0.46 / Connector/J 9.7.0 |
Ubuntu 24.04 mysql-server-core-8.0 package |
| hypersistence-utils | hypersistence-utils-hibernate-73 3.16.0 |
hypersistence profile only (A10) |
| Java | 25 (Temurin 25.0.5+8) |
Quickstart
./scripts/start-databases.sh # PostgreSQL on 55432 and MySQL on 53306 (needs root: both servers refuse to run as root, so it makes two OS users)
./scripts/run-all.sh # versions + mvn clean test + hypersistence runs + FormatMapper matrix; regenerates everything in output/
Point the tests at other servers with PG_URL, PG_USER, MYSQL_URL, MYSQL_USER (defaults in src/test/java/com/ankurm/jsoncolumns/Db.java).
Timings in output/07-indexing-explain.txt drift between runs; plan shapes and row counts are asserted.
Layout
| Path | What |
|---|---|
src/main/java/.../model |
Product (Map, List, record, POJO columns), Dimensions (record), Specs (POJO with equals()), Event (indexing table), ProductRepository, SharedMapperConfig, JsonColumnsApplication |
src/test/java/.../A01..A11 |
one test class per output file (A10 lives in src/hypersistence-test, active with -Phypersistence) |
src/test/java/.../Db.java, SqlLog.java, Transcript.java, HqlRunner.java, Seed.java |
plain-Hibernate bootstrap, SQL capture, transcript writer, shared HQL case runner, shared sample rows |
src/test/java/.../FormatMapperProbe.java |
main() run by scripts/format-mapper-matrix.sh under nine classpaths |
scripts/ |
start-databases.sh, run-all.sh, versions.sh, format-mapper-matrix.sh, javap.sh, maven-facts.sh |
Output
| File | What it shows |
|---|---|
00-versions.txt |
JDK, resolved library versions, PostgreSQL and MySQL server versions |
01-ddl-postgresql.txt |
the CREATE TABLE Hibernate emits for six JSON mappings (json vs jsonb), json vs jsonb storage differences |
02-mapping-roundtrip.txt |
Map / List / record / POJO round trip: INSERT, stored JSON, Java types that come back, null vs empty |
03-dirty-checking.txt |
in-place mutations detected or not, spurious UPDATEs (no equals(), BigDecimal), @DynamicUpdate |
04-hql-json-functions-postgresql.txt |
every Hibernate 7.4 HQL JSON function run on PostgreSQL 18: generated SQL and result |
05-embeddable-json-postgresql.txt |
@Embeddable stored as JSON, navigated in HQL without json_value() |
06-native-jsonb-operators.txt |
->>, @>, ?, @?, @@ in native queries and what Hibernate's parameter parser does to them |
07-indexing-explain.txt |
50,000 rows, EXPLAIN (ANALYZE) before and after GIN, jsonb_path_ops and expression indexes |
08-mysql.txt |
DDL, round trip, dirty checking, HQL functions, native functions and indexes on MySQL 8.0 |
09-format-mapper-matrix.txt |
which FormatMapper Hibernate picks under nine classpath / setting combinations |
09-format-mapper-inprocess.txt |
schema evolution failures, @JsonIgnoreProperties, a custom JsonMapper, java.time inside a Map |
10-hypersistence-*.txt |
@TypeDef is gone; hypersistence-utils JsonType on Hibernate 7.4.14 with and without Jackson 2 |
11-spring-boot.txt |
Spring Data repositories with native and HQL JSON queries; Boot's JsonMapper is not Hibernate's |
12-javap-deepcopy.txt |
javap of the JSON snapshot copy (deepCopy = serialise then parse) and of areEqual (Objects.equals) |
13-maven-facts.txt |
release dates and maven-metadata.xml facts read from Maven Central (versions callout, hypersistence-utils vs the old hibernate-types) |
Not covered (not run)
Oracle, SQL Server, DB2, H2 and MariaDB JSON dialects, Hibernate's JSON mapping with SqlTypes.JSON_ARRAY, @Embeddable aggregates on MySQL beyond a single query,
jsonb_path_ops plus @? path indexing, PostgreSQL jsonb_ops write amplification, concurrent-write load, JsonB (Yasson) as the format mapper, and Hibernate 8.
MIT — see LICENSE.