I think we’re looking at it from different perspectives. You seem to be looking at it from a perspective of “how can we minimize the amount of undefined behavior hibernate produces”. I’m looking at it from a perspective of “If I pass correct values (and types) to Hibernate I’d like to get correct results”. In the case of multiplication of with 1+ unknown values unspecified behavior could occur, depending on the specific types. For the types int and double the list sort of looks like this:
- Valid computations:
- (int, int) → int
- (int, int) → double
- (double, int) → double (and the symmetric case)
- (double, double) → double
- Invalid / undefined computations:
- (double, int) → int
- (double, double) → int
When hibernate cannot (feasibly?) know which of these cases it’s in you’d prefer to err on the side of “excluding undefined behavior”, that is ideally all of these throw an exception. At least that’s my impression. And honestly, that sounds pretty good? But I guess a way to do math in HQL is desirable? In which case there needs to be a way to communicate the unknown types to Hibernate so that it can know it’s in a valid case and does not error. I think your proposal is to have something akin to an explicit type cast be part of the query? On first glance it seems to be me that the information is already present in a stronger the form of the parameter type. Contrast the following examples:
Object value = "foo";
session.createQuery("... SET test.bigDecimalField = test.intField * cast(?1 as int) FROM ...")
.setParameter(1, value)...
int value = 1;
session.createQuery("... SET test.bigDecimalField = test.intField * ?1 FROM ...")
.setParameter(1, value)...
int value = 1;
session.createQuery("... SET test.bigDecimalField = test.intField * cast(?1 as int) FROM ...")
.setParameter(1, value)...
My impression is that version 3 is what you’re thinking but it seems not obviously better to me than version 2. Perhaps it is, you’re certainly more familiar with the topic than I am. But let me lay out my thinking: Version 1 and 3 communicate the intended type of ?1 in the query but as version 1 demonstrates that is not reliable, as I can write any type I want in the query string. Version 2 and 3 communicate the intended type of ?1 via the type of value which is enforced by the java typing system. Not perfectly reliable perhaps but more reliable than version 1 for it seems to me. Given that, what does version 3 add that version 2 does not provide? Requiring cast(?1 as double) when ?1 is of type int seems weaker than requiring the java-type of value to be double and requiring both seems redundant to me. |