java - org.hibernate.criterion - I need to OR together an arbitrary number of criterion? -
i have java application using (quite old) hibernate mapping oracle 11 database. i'm using org.hibernate.criterion class generate queries (at least piece).
i hit bug 1 of queries i'm generating using org.hibernate.criteria produces large 'in' clause. here's how java console displays generated query:
select this_.foo foo_1_2_3, this_.bar bar_2_3_4, this_.id id_5_6_7 some_table inner join some_other_table inner join blah=bloo , this_.id in (?, ?, ?, ?, ?, ......................... ?, ?, ?, ?) order this_.id asc
where number of ?
elements >1000.
this in clause large triggers ora-01795: maximum number of expressions in list 1000
error in our database.
here's java code adds 'in' clause:
criteria.add(restrictions.in("id", getmassivelistofids() ) );
(where i'm adding >1000 element in clause, in other words)
according this stackoverflow question using multiple smaller 'in' clauses solution. makes sense.
i've modified splits lists before adding 'in' queries, so:
list<long> listofids = getmassivelistofids(); if(listofids.size()>=1000){ list<list<long>> listofsublists = this.splitintosubarrays(listofids); for(list<long> subarray : listofsublists){ criteria.add(restrictions.in("id", subarray)); } }else{ criteria.add(restrictions.in("id", listofids)); }
so generated query this:
select this_.foo foo_1_2_3, this_.bar bar_2_3_4, this_.id id_5_6_7 some_table inner join some_other_table inner join blah=bloo , this_.id in (?, ?, .... ?, ?) , this_.id in (?, ?, .... ?, ?) , this_.id in (?, ?, .... ?, ?) , this_.id in (?, ?, ?, ?, ?, ?) order this_.id asc
where each of (?, ?, .... ?, ?, ?)
arrays contain 1000 elements, , last remainder.
the problem these and
, not or
want or of in clauses(in other words, want fetch rows have id listed in of these clauses), like:
select this_.foo foo_1_2_3, this_.bar bar_2_3_4, this_.id id_5_6_7 some_table inner join some_other_table inner join blah=bloo , ( this_.id in (?, ?, .... ?, ?) or this_.id in (?, ?, .... ?, ?) or this_.id in (?, ?, .... ?, ?) or this_.id in (?, ?, ?, ?, ?, ?) ) order this_.id asc
i know this:
criterion c1 = restrictions.in("id", sublist1); criterion c2 = restrictions.in("id", sublist2); criterion c3 = restrictions.in("id", sublist3); criterion c4 = restrictions.in("id", sublist4); criterion or1 = restrictions.or(c1, c2); criterion or2 = restrictions.or(c3, c4); criteria.add(restrictions.or(or1, or1) );
but have no idea @ compile time how big listofids be. 500 or 10000.
is there way either
dynamically produce oring shown above
or arbitrarily sized list of criterion , add them query?
i realize niche question, appreciate or advice. i've massively simplified examples sake of illustration.
really, i'm looking java code solution, rather change database or hibernate mapping if @ possible.
many thanks.
you need this:
if (arguments.size() > 1000) { criterion criterionin = restrictions.sqlrestriction("1<>1"); final list<serializable> inlist = new arraylist<serializable>(); (int = 0; < arguments.size(); i++) { inlist.add(arguments.get(i)); if (inlist.size() == 1000) { criterionin = restrictions.or(criterionin, restrictions.in(restriction.getfield(), inlist)); inlist.clear(); } } if (!inlist.isempty()) { criterionin = restrictions.or(criterionin, restrictions.in(restriction.getfield(), inlist)); } final criterion criterionnotin = restrictions.not(criterionin); return criterionnotin; }
a complete example can find on github
Comments
Post a Comment