jdaugherty commented on PR #16020:
URL: https://github.com/apache/grails-core/pull/16020#issuecomment-5018622763

   The direction is right, but rather than overriding the JDBC type via 
`setExplicitJdbcTypeAccess(SqlTypes.LONG32VARCHAR)`, consider leaning on 
Hibernate's capacity-dependent DDL type mechanism instead.
   
   Why `text` fails while `clob` works: `type: 'text'` resolves to 
`StandardBasicTypes.TEXT` (`Types.LONGVARCHAR`), which since Hibernate 6 is no 
longer a LOB code — it's registered as a "long variant of varchar" and, with no 
explicit length, gets the implied default `Length.LONG` (32600). The dialect's 
capacity registry then correctly renders a bounded `varchar(32600)` because 
32600 fits below the switch-over threshold. `Types.CLOB` has no length 
semantics, so dialects render their native unbounded type directly.
   
   Hibernate 6 introduced exactly this mechanism as the replacement for the 
removed `TextType` and friends: `@Column(length = Length.LONG32)` is the 
documented way to get an unbounded string column without `@Lob` (see the 
Hibernate 6 migration guide's "Basic Types / LONGVARCHAR" changes and 
`org.hibernate.Length`). Setting `column.setLength(Length.LONG32)` lets every 
dialect's capacity-based DDL registry pick its own unbounded type (`text` on 
Postgres, `longtext` on MySQL, `varchar(max)` on SQL Server, `clob` on 
Oracle/H2) with no per-dialect assumptions.
   
   One wrinkle worth addressing at the mapping level: GORM always defaults a 
length for string columns (the length is never truly "unset" by the time the 
column is bound), so there is currently no way for a user to express 
"unbounded" other than smuggling it through a type name like `text`. It may be 
cleaner to support a null/unset length in the column config as a first-class 
way to say unbounded — mapping it to `Length.LONG32` at bind time — rather than 
special-casing the `text` type name. That gives users an explicit knob that 
works with any string type, and `type: 'text'` can then just be the case that 
opts into it by default.
   
   Advantages over the explicit-JDBC-type override:
   
   - Uses the public, dialect-portable mechanism instead of bypassing type-name 
binding (`setTypeName` is currently skipped in the `text` branch while 
`setTypeParameters` still runs).
   - Composes naturally with `maxSize`/`inList`/explicit `column length:` — an 
explicit bound simply keeps the column bounded, preserving prior behavior, 
whereas the JDBC-type override plus `StringColumnConstraintsBinder` setting a 
length now produces dialect-dependent results.
   - Avoids forcing a character JDBC descriptor onto any property whose 
resolved type name happens to be `text` regardless of its Java type.
   
   A couple of test asks either way:
   
   - The only coverage is the Postgres Testcontainers spec gated on 
`isDockerAvailable()` — a container-less CI run exercises none of this. An 
H2-based DDL assertion would cover the default path everywhere.
   - A test for `type: 'text'` combined with `maxSize:` — that combination 
previously produced `varchar(maxSize)` on all dialects and its behavior is now 
unspecified.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to