我正在使用java / hibernate / Oracle。我有一个包含超过3000个条目的列表。如果我通过整个列表,我会得到以下异常。
引起:java.sql.SQLException:ORA-01795:列表中的最大表达式数为1000
解决问题我将列表拆分为子列表,每个子列表将有1000个条目。对于每千个条目我正在触发查询。它工作正常。
请澄清我,有没有更好的解决方案?
谢谢!
答案 0 :(得分:7)
这是一个Oracle限制,这就是为什么它有一个Oracle错误代码......虽然你可以说它是Hibernate的一个限制,它不会透明地解决它:)
您应该将列表放入临时表并加入其中,假设Oracle没有SQL Server的table-valued parameters之类的内容。 (或者你可以将你的查询分解为多个查询,potentailly - 这取决于你正在做什么。)
答案 1 :(得分:1)
异常 - 文本让我相信这来自Oracle数据库 - 查看错误号...
答案 2 :(得分:0)
还有另一种解决此问题的方法。假设你有两个表Table1和Table2。并且需要使用Criteria查询获取Table2中未引用/存在的Table1的所有条目。 所以继续这样......
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();
.
.
.
它将直接在SQL中执行所有子查询检查,而不包括由Hibernate框架转换的SQL中的1000个或更多参数。它对我有用。 注意:您可能需要根据您的要求更改SQL部分。
答案 3 :(得分:0)
如果您使用的是Oracle DB,则无法在单个“where”条件下拥有超过1000个元素的列表。因此,您可以在多个“where”条件中删除“where”条件,并使用“or”子句加入它们。
如果您正在使用hibernate Criteria,则可以使用以下Java方法执行此操作。 只需在您使用过的地方替换代码
criteria.add(Restrictions.in(propertyName, mainList));
带
addCriteriaIn(propertyName, mainList, criteria);
方法是:
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);
}
答案 4 :(得分:0)
我在下面使用过,对我来说效果很好
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)
}
}