Ruben Gehring ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=6401f5e... ) *commented* on HHH-16986 ( https://hibernate.atlassian.net/browse/HHH-16986?atlOrigin=eyJpIjoiOTQyYW... )
Re: CoercionException caused by attempted coercion of query param to entity field type ( https://hibernate.atlassian.net/browse/HHH-16986?atlOrigin=eyJpIjoiOTQyYW... )
Two more points:
* Ideally the type of a parameter would depend on the parameter only, that is be independent of the result type.
In cases where the result is based on a calculation it should be possible to pass in all kinds of types for the operands. For example passing 2.5d and 2f to a calculation expected to return Integer seems fine to me, and I would expect the result of (int) (2.5d * 2f) to be 5.
* Hibernate is usually really good at this, too! It only seems to fail when I use an entity field in the calculation (which I wish I didn’t have to but that’s another discussion)
Consider the following almost-identical queries:
// Let test.intField be initialized to 2, int
session.createQuery("""
UPDATE TestEntity test
SET test.bigDecimalField = test.intField * ?1
""")
.setParameter(1, BigDecimal.valueOf(2.5d))
.executeUpdate();
// Result: Parameter value [2.5] did not match expected type [BasicSqmPathSource(intField : Integer ) ]
// Let passing same value (2, int ) as a query param instead of reading the entity field
session.createQuery("""
UPDATE TestEntity test
SET test.bigDecimalField = ?1 * ?2
""")
.setParameter(1, 2)
.setParameter(2, BigDecimal.valueOf(2.5d))
.executeUpdate();
// Result: Update successful, value of 5.00 confirmed in entity
( https://hibernate.atlassian.net/browse/HHH-16986#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16986#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100233- sha1:f5b6255 )
Gavin King ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *commented* on HHH-16986 ( https://hibernate.atlassian.net/browse/HHH-16986?atlOrigin=eyJpIjoiY2IyOT... )
Re: CoercionException caused by attempted coercion of query param to entity field type ( https://hibernate.atlassian.net/browse/HHH-16986?atlOrigin=eyJpIjoiY2IyOT... )
>
>
>
> the other half are modifying queries on an entity where I’d imagine the
> return type of the calculation should be known
>
>
Right, that’s what I was alluding to when I said:
>
>
>
> there are some related cases where we probably could do better
>
>
though I was thinking more of the case of such an expression occurring in a where clause.
But it’s really not as simple as you imagine, since we can have quite complex expressions involving parameters and functions and operators and allowing things like this would mean not type checking the whole expression as soon as the expression involves a parameter and a numeric operator. That’s a bit nasty.
And yes, of course we could make it work in a piecemeal way for some special cases. But that’s a bad way to design languages. I much prefer bright-line rules about what is allowed and what is disallowed. Otherwise you end up with Perl.
So it’s simply unclear whether this is something we should even try to fix. (I need to talk it over with Steve.)
>
>
>
> I guess it might just have copied over the anticipated type of the operand
> it does know ( test.intField ) to the operand it does not know.
>
>
Right, that’s exactly what it does: it infers the parameter type from the other operand. This is the best it can do in general. What you’re asking the query compiler to do is an implicit numeric type promotion to a type it has no way of knowing. That’s asking for rather a lot. In general, it’s asking for the impossible.
Now, one option which I’ve toyed with a bit is allowing the type of parameters to be declared explicitly, something like:
select test.intField * BigDecimal?1
select test.intField * BigDecimal: name
or:
select test.intField * (?1 as BigDecimal)
select test.intField * (: name as BigDecimal)
or whatever.
This would solve the problem completely.
In the meantime, I don’t think the obvious workaround is that terrible:
select cast(test.intField as BigDecimal) * ?1
This is just barely more verbose than the proposed new syntax (one extra token).
Implicit type promotions can always be rewritten as explicit casts, so this workaround always works.
( https://hibernate.atlassian.net/browse/HHH-16986#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16986#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100233- sha1:f5b6255 )