Replace isMapValueTypeObject + isMapStringString with isBuiltinJsonMap:
the built-in JSON map handles a String or enum key with a String, Object
or wildcard value. This also routes Map<Enum,String> to the built-in type
and fixes non-String/enum keys with Object value (e.g. Map<Integer,Object>)
being mis-routed to the built-in type (ClassCastException) instead of the
object mapper.
Addresses #3735. Enum-keyed JSON maps previously failed (enum key cast to
String). Add ScalarTypeJsonMapEnum which converts enum keys via their
ScalarType (honouring @DbEnumValue) and reuses ScalarTypeJsonMap for all
storage/platform handling, so it works for VARCHAR/CLOB/BLOB and Postgres
JSON/JSONB with no per-storage variants.
- JsonStorage now reports jdbcType(), enabling a shared storageFor(...) reused
by the plain and enum-key Map types
- DefaultTypeManager routes Map<Enum,Object> to the new type and calls
setAccessible on the @DbEnumValue method (supports nested/non-public enums)
- add TypeReflectHelper.getMapKeyTypeRaw and TestEnumKeyMap
Collapse the per-storage and per-platform ScalarType subclass explosion for the built-in JSON value types into two orthogonal strategies.
- Add JsonStorage strategy (VARCHAR / CLOB / BLOB / Postgres) encapsulating
how the raw JSON string is read from / bound to JDBC. Postgres vs
non-Postgres is now a single reusable strategy rather than a subclass per
value type.
- Add ScalarTypeJsonValue<T> base holding the shared read / bind / L2-cache /
json plumbing once, plus ScalarTypeJsonCollectionValue<T> adding the
ScalarTypeArray (DB array column definition) aspect for List/Set.
- Rewrite ScalarTypeJsonMap, ScalarTypeJsonList and ScalarTypeJsonSet as thin
types: a typeFor factory selecting a JsonStorage + value marshalling that
delegates to the avaje-JsonMapper-backed EJson facade.
- Remove ScalarTypeJsonMapPostgres and ~16 nested storage/platform classes.
Reworks the DJsonService (the SpiJsonService SPI behind io.ebean.text.json.EJson) to use avaje JsonMapper instead of the bespoke EJsonReader/EJsonWriter, consolidating all read/write logic into a single JsonAdapter.
Changes
- New EbeanJsonAdapter — a JsonAdapter<Object> that materializes JSON into plain or modify-aware Map/List/Set, with two shared singletons (PLAIN, MODIFY_AWARE). Preserves existing EJson semantics: - Integral numbers → Long, decimals → BigDecimal
- Write coverage for String/Integer/Long/Double/Float/BigDecimal/Boolean/Map/Collection with a toString() fallback for other types (UUID, enum, etc.)
- Modify-aware loads share a single ModifyAwareFlag owner per root, reset to non-dirty once after the load completes
- DJsonService now builds one JsonMapper + two JsonMapper.Type<Object> and routes parse/write through them. Null serialization is retained via a serializeNulls(true) writer; null/blank-input guards, token-honoring entry points, and parseSet (modify-aware asSet()) are preserved.
- EJsonReader/EJsonWriter are now unused and should be deleted (couldn't remove them in this environment).
Why
Simplifies Ebean's JSON handling by reusing avaje-json-core's JsonMapper rather than maintaining a parallel reader/writer, while keeping behavior identical.
So when we used to get an inline comment like:
```sql
select /* Customer.hiLabel */ ...
```
We started to instead have (missing bean type):
```sql
select /* hiLabel */ ...
```
This fixes that regression that was introduced in #3779
This allows for customisation of the built in I__ init scripts.
For the case of postgres db partitions a customisation to support
unlogged tables was for example always being overwritten.
This change makes the I__ scripts a "add if not already exists".
Note that R__ repeatable scripts are "always overwrite"