Greetings,
I have this question (problem, if you wish) for which I failed to get an answer (OK, solution...).
The thing is that my goal is, bottom line, to get a SQL that has is WHERE clause look something like this:
Code:
WHERE (col1, col2) IN ( (1, 10), (2, 20) )
But how do I write such an HQL (giving that the number of tuples is dynamic)?...
I have consulted about this question with some of my colleagues, and they offered me to write an HQL that looks something like:
Code:
<query name="myQuery">
from myObj as mo
where mo.prop1 in (:values1)
and mo.prop2 in (:values2)
</query>
But this wouldn't do.
Let's say that in my example above I have 1 and 2 as the values of prop1, and 10 and 20 as the values of prop2.
So using the suggested query above would generate a SQL that includes all the permutations, something which is equivalent to the following:
Code:
WHERE (col1, col2) IN ( (1, 10), (1, 20), (2, 10), (2, 20) )
And that not what I am looking for, as (1, 20) and (2, 10) are invalid combination for my needs...
I have thought of several alternatives, but I am not sure which is valid, if any...
Idea 1The query in the hbm.xml will look like the following:
Code:
<query name="myQuery">
from myObj as mo
where (mo.prop1, mo.prop2) in ((:val1, :val2))
</query>
But I am not sure how Hibernate treats this (:val1, :val2). Would it treat it as properties of the tuple, or would it treat it as items of the IN operator?
In other words, would it expect :val1 to be, in my example, (1, 10) and :val2 to be (2, 20), or :val1 to be 1 and :val2 to be 10?
If it is the first (:val1 as (1, 10) and :val2 as (2, 20)), then how can I write such an HQL where the number of tuples is dynamic (i.e., having the tuples (1, 10), (2, 20), (3, 30), (4, 40), ...)?
Or, if it is the later (:val1 as 1 and :val2 as 10), then how do I set the values, say, using the HibernateTemplate? The findByNamedQueryAndNamedParam API accepts an array of Object-s as the values. This may allow me to pass it an Object array as its items, e.g.,
Code:
List executeMyQuery(HibernateTemplate tmplate) {
Object[] val1= new Integer[] {1, 2};
Object[] val2= new Integer[] {10, 20};
Object[] values= new Object[] {val1, val2};
String[] paramNames= {"val1", "val2"};
return template.findByNamedQueryAndNamedParam("myQuery", paramNames, values);
}
But would it do? Would Hibernate know to bind the values by their index, or would it generate all the permutations? Or would it throw some nasty exception?...
Idea 2The query would look like the following:
Code:
<query name="myQuery">
from myObj as mo
where (mo.prop1, mo.prop2) in (:val1)
</query>
Would it pass validation?
If so, then the following code would work?
Code:
List executeMyQuery(HibernateTemplate tmplate) {
Object[] val1= new Integer[] {1, 10};
Object[] val2= new Integer[] {2, 20};
Object[] values= new Object[] {val1, val2};
String[] paramNames= {"val1"};
return template.findByNamedQueryAndNamedParam("myQuery", paramNames, values);
}
Idea 3Same HQL as in idea 2:
Code:
<query name="myQuery">
from myObj as mo
where (mo.prop1, mo.prop2) in (:val1)
</query>
But a different approach to set the values by the application:
Code:
List executeMyQuery(HibernateTemplate tmplate) {
Object[] values= new Object[] {"(1, 10)", "(2, 20)"};
String[] paramNames= {"val1"};
return template.findByNamedQueryAndNamedParam("myQuery", paramNames, values);
}
I do not know which approach will work, if any...
If none, then how should I do it?
And in case there are several approaches that will work, what would be the best?
Thanks in advance (and sorry for the long text...),
Ohad