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

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -