Reputation: 12621
I am using java/hibernate/Oracle. i have a list with more than 3000 entries. if i pass whole list i get below exception.
Caused by: java.sql.SQLException: ORA-01795: maximum number of expressions in a list is 1000
to solve the issue i am splitting the list into sublists, each sublist will have 1000 entries. for every thousand entries i am firing a query. it is working fine.
Please clarify me, is there any better solution?
Thanks!
Upvotes: 5
Views: 11240
Reputation: 1
i have used below and it works perfectly for me
if (myArgList.size() > 1000) {
while(myArgList.size()>0)
{
tempList = myArgList;
def listSize= tempList.size()
if(listSize>1000){
def subList = tempList.subList(0, 1000);
def tcriteria = tableA.createCriteria()
result.addAll(tcriteria.listDistinct {
'in'('id', subList.collect{it.id})
fetchMode('tableBObj', FetchMode.JOIN)
})
myArgList.subList(0, 1000).clear();
}else{
def subList = myArgList.subList(0, listSize);
def ncriteria = tableA.createCriteria()
result.addAll(ncriteria.listDistinct {
'in'('id', subList.collect{it.id})
fetchMode('tableBObj', FetchMode.JOIN)
})
myArgList.clear();
}
}
} else {
def criteria = tableA.createCriteria()
result = criteria.listDistinct {
'in'('id', myArgList.collect{it.id})
fetchMode('tableBObj', FetchMode.JOIN)
}
}
Upvotes: 0
Reputation: 93
there is also another way to resolve this issue. lets say you have two tables Table1 and Table2. and it is required to fetch all entries of Table1 not referred/present in Table2 using Criteria query. So go ahead like this...
List list=new ArrayList();
Criteria cr=session.createCriteria(Table1.class);
cr.add(Restrictions.sqlRestriction("this_.id not in (select t2.t1_id from Table2 t2 )"));
.
.
List list=new ArrayList();
Criteria cr=session.createCriteria(Table1.class);
cr.add(Restrictions.sqlRestriction("this_.id not in (select t2.t1_id from Table2 t2 )"));
list=cr.list();
.
.
.
It will perform all the subquery finction directly in SQL without including 1000 or more parameters in SQL converted by Hibernate framework. It worked for me. Note: You may need to change SQL portion as per your requirement.
Upvotes: 0
Reputation: 141
You cant have a list with more than 1000 elements in a single "where" condition if you are working with Oracle DB. So you can chop down your "where" condition in multiple "where" conditions and join them with "or" clause.
If you are using hibernate Criteria, you can use below Java method to do this. Just replace your code where ever you used
criteria.add(Restrictions.in(propertyName, mainList));
with
addCriteriaIn(propertyName, mainList, criteria);
which the method is :
private void addCriteriaIn (String propertyName, List<?> list,Criteria criteria)
{
Disjunction or = Restrictions.disjunction();
if(list.size()>1000)
{
while(list.size()>1000)
{
List<?> subList = list.subList(0, 1000);
or.add(Restrictions.in(propertyName, subList));
list.subList(0, 1000).clear();
}
}
or.add(Restrictions.in(propertyName, list));
criteria.add(or);
}
Upvotes: 0
Reputation: 1499790
It's an Oracle limitation, which is why it's got an Oracle error code... although you could argue that it's a limitation of Hibernate that it doesn't transparently work around it :)
You should probably put the list into a temporary table and join on that, assuming Oracle doesn't have anything like SQL Server's table-valued parameters. (Or you could break your query up into multiple queries, potentailly - it depends on what you're doing.)
Upvotes: 8
Reputation: 2635
The Exception-Text lets me believe that this is coming from the Oracle-Database - look at the error-number...
Upvotes: 0