fix: EXPOSED-116 UUID conversion error with upsert in H2 #1823
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Using a UUID column as a key
id
constraint in H2'sMERGE INTO .. USING
statement fails with:This error occurs because the statement uses a derived column list to merge
ON (T.ID=S.ID)
, so the UUID as aByteArray
stored in T.ID needs to be converted internally to compare with theString
in S.ID (from generated SQL). This error goes away if a regular integerid
column is used or if the key constraint is swapped with another non-UUID type.The error also goes away if an identical MERGE statement is placed in
exec()
directly, indicating that the issue lies with how Exposed sends UUID values to the H2 database.Switching the sent value from a ByteArray to a String allows comparison without conversion. A String is still one of 3 acceptable ways to store a UUID in H2 and sending a String still results in a UUID being retrieved back from the database (via
valueFromDB()
andreadObject()
).Additional:
RAW(16)
type instead of H2'sUUID
type and leads to a second error:To resolve this, H2_Oracle could also be made to use the Oracle-specific UPSERT statement, but this syntax fails when sent to H2. Instead, the compatibility mode now uses the
H2DatatypeProvider
overrides.