JPA Attribute Converter ignored in Criteria Query Where Clause
Description
Activity
Show:
Daniel M. December 22, 2022 at 2:02 PM
This issue is fixed in {{6.0.1.Final}} upwards.
Fixed
Details
Details
Assignee
Unassigned
UnassignedReporter
Daniel M.
Daniel M.Components
Priority
Created July 27, 2021 at 3:51 PM
Updated July 12, 2024 at 4:05 PM
Resolved July 12, 2024 at 4:05 PM
When using a JPA Attribute Converter which converts numeric basic types in a
WHERE
Clause in a Criteria Query, the Attribute Converter is not used when the supplied numeric literal is negative.A little background to the issue: X509 certificate serial numbers represented as Java
BigIntegers
should be persisted as uppercase Hex Strings in aVARCHAR
Table Column. To convert betweenBigInteger
s and Strings, a JPA Attribute Adapter is used. Everything works fine, except for one thing: When using the convertedBigInteger
field to query the database using the Criteria API, the serial number is not converted and the database returns an error because the type does not match (ORA-01722: invalid number). This only happens when the literal used in theWHEN
clause is negative though. Positive literals work fine.The issue seems to be related to how the AST is built for the resulting HQL Query, since a negative integer literal is split into separate AST Nodes. A
UnaryArithmeticNode
does not implement theExpectedTypeAwareNode
Interface, which results in theBinaryLogicOperatorNode
not applying the Property Adapter to the right hand side of the equals expression. The literal is therefore not converted into the correct type.HQL AST for the failing query:
\-[QUERY] Node: 'query' +-[SELECT_FROM] Node: 'SELECT_FROM' | +-[FROM] Node: 'from' | | \-[RANGE] Node: 'RANGE' | | +-[DOT] Node: '.' | | | +-[DOT] Node: '.' | | | | +-[DOT] Node: '.' | | | | | +-[DOT] Node: '.' | | | | | | +-[IDENT] Node: 'org' | | | | | | \-[IDENT] Node: 'hibernate' | | | | | \-[IDENT] Node: 'converter' | | | | \-[IDENT] Node: 'entity' | | | \-[IDENT] Node: 'Car' | | \-[ALIAS] Node: 'generatedAlias0' | \-[SELECT] Node: 'select' | \-[IDENT] Node: 'generatedAlias0' \-[WHERE] Node: 'where' \-[EQ] Node: '=' +-[DOT] Node: '.' | +-[IDENT] Node: 'generatedAlias0' | \-[IDENT] Node: 'serial' \-[UNARY_MINUS] Node: '-' \-[NUM_BIG_INTEGER] Node: '11BI'
A sample project showcasing the issue is located over at GitHub.