Fix non-portable BLOB columnDefinition in WebAuthnCredential#275
Fix non-portable BLOB columnDefinition in WebAuthnCredential#275devondragon merged 2 commits intomainfrom
Conversation
Remove hardcoded `columnDefinition = "BLOB"` from three byte[] fields in WebAuthnCredential. The `@Lob` annotation already handles dialect- appropriate type mapping (BLOB for MySQL, bytea for PostgreSQL, etc.). The explicit columnDefinition bypassed Hibernate's dialect translation, causing DDL failures on PostgreSQL and other non-MySQL databases. Fixes #274
Code ReviewThis is a correct and well-scoped fix. Removing the hardcoded What the fix does well
Things worth verifying before merge1. PostgreSQL: In Hibernate 6 (used by Spring Boot 3.5+/4.0+),
The original reporter (#274) should verify that this actually works end-to-end on PostgreSQL, not just that DDL generation succeeds. If @JdbcTypeCode(Types.VARBINARY)
@Column(name = "public_key", nullable = false)
private byte[] publicKey;That said, 2. Existing MySQL users — schema drift This library has no Flyway/Liquibase migrations, so consumers using 3. This was true before the PR too, but worth confirming intentionally: Test coverageThe H2 tests passing is a good baseline. Recommend the #274 reporter confirms:
SummaryApproved with notes. The fix is correct and directly addresses the reported issue. The Hibernate 6 + PostgreSQL |
There was a problem hiding this comment.
Pull request overview
This PR simplifies the JPA mapping for WebAuthn binary fields by removing explicit columnDefinition = "BLOB" declarations and relying on @Lob + the configured Hibernate dialect to choose the appropriate underlying column type.
Changes:
- Removed explicit
columnDefinition = "BLOB"from thepublic_keycolumn mapping. - Removed explicit
columnDefinition = "BLOB"fromattestation_objectandattestation_client_data_jsoncolumn mappings.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace `@Lob @column(columnDefinition = "BLOB")` with plain `byte[]` and explicit `@Column(length = ...)` on the three binary fields in WebAuthnCredential. `@Lob` on byte[] in Hibernate 7 generates literal `blob` in DDL, which bypasses dialect translation and fails on PostgreSQL (no `blob` type). Plain byte[] lets each dialect choose the correct native type: `bytea` on PostgreSQL, `varbinary`/`mediumblob` on MySQL. Verified DDL generation against a real PostgreSQL 16 instance and confirmed all three columns map to `bytea`. Full H2 test suite passes with no regressions. Fixes #274
Code ReviewThe fix is correct in spirit — removing PR description vs. actual diffThe summary says "The existing Removing So the approach — Concrete concern:
|
| Length | MySQL DDL type |
|---|---|
| ≤ 255 | TINYBLOB |
| ≤ 65535 | BLOB |
| ≤ 16,777,215 | MEDIUMBLOB |
length = 65536 is 1 byte over the BLOB threshold, so Hibernate will generate MEDIUMBLOB for attestation_object and attestation_client_data_json.
Why this matters for existing MySQL users:
- Users running with
ddl-auto=updatewould see Hibernate attempt to alterBLOB→MEDIUMBLOB, which may fail or cause unintended schema churn. - Most production setups use
validateornone, so the practical impact is limited — but worth being intentional.
Recommendation: Change to length = 65535 to stay within the BLOB bucket on MySQL while still supporting up to 64 KB of attestation data. Attestation objects in practice are well under this limit.
// Before
@Column(name = \"attestation_object\", length = 65536)
// After
@Column(name = \"attestation_object\", length = 65535)
@Column(name = \"attestation_client_data_json\", length = 65535)publicKey with length = 2048 looks correct
2048 bytes comfortably covers all COSE key types (EC2, RSA, OKP). Maps to BLOB on MySQL (> 255) and bytea on PostgreSQL. No concerns here.
Summary
| Item | Assessment |
|---|---|
Remove columnDefinition = \"BLOB\" |
Correct fix |
Remove @Lob |
Good — avoids PostgreSQL oid complications |
length = 2048 for publicKey |
Fine |
length = 65536 for attestation fields |
Minor issue — off-by-one past MySQL BLOB threshold; change to 65535 |
| PR description accuracy | Should be updated to reflect that @Lob is also removed |
Overall this is a solid, necessary fix. The 65536 → 65535 tweak and a description update are the only suggested changes before merge.
Summary
columnDefinition = "BLOB"from threebyte[]fields inWebAuthnCredential(publicKey,attestationObject,attestationClientDataJson)@Lobannotations — plainbyte[]with explicitlengthhints lets Hibernate pick the right native type per dialect without the inconsistent@Lobsemantics across Hibernate versionslength = 65535(not 65536) forattestationObjectandattestationClientDataJsonto stay within MySQL's BLOB threshold and avoid unexpected MEDIUMBLOB promotionpublicKeyuseslength = 2048which fits comfortably in a standard BLOBFixes #274
Test plan