简体   繁体   中英

Transform sql to hibernate criteria

I am writing a method for retrieving clients with sum of their orders (order.total) higher and less than input values.

Criteria criteria = DetachedCriteria.forClass(Clients.class, "cl");

if (clOrdsTtlPrcFrom != -1 && clOrdsTtlPrcTo != -1) {
            String sql = "select OwnerID from Orders group by OwnerID having sum(Total) >= :clOrdsTtlPrcFrom and sum(Total) <= :clOrdsTtlPrcTo";
            SQLQuery query = sess.createSQLQuery(sql).addScalar("OwnerID", LongType.INSTANCE);
            query.setParameter("clOrdsTtlPrcFrom", clOrdsTtlPrcFrom);
            query.setParameter("clOrdsTtlPrcTo", clOrdsTtlPrcTo);
            criteria.add(Restrictions.in("id", query.list()));
        }


Criteria criteria2 = sess.createCriteria(Clients.class);
        criteria2.add(Subqueries.propertyIn("id", criteria));
List<Clients> clients = (List<Clients>) criteria2.list();

All its okay, but, sometimes i am get an error:

java.sql.SQLException: Prepared or callable statement has more than 2000 parameter markers.

How can i correcting this method, or, maybe, convert this in full criteria style?

java.sql.SQLException : Prepared or callable statement has more than 2000 parameter markers`.

You can learn more what this error means when you cannot have the list of input parameters to be more than 2000. The solution is that you need to either split the large list into smaller ones or optimize your SQL query to have less than limited size of parameters.

You have to fix this issue by partitioning the list into small lists of size less than 2000 and then run the query for each of those smaller lists. Then combine the results into one list again. Now you can partition the list the way you want.

In the end, i solved this problem by this way, using sql restriction:

DetachedCriteria dtcrt = DetachedCriteria.forClass(Clients.class);
        dtcrt.setProjection(Projections.distinct(Projections.id()));    
if (clOrdsTtlPrcFrom != -1 && clOrdsTtlPrcTo != -1) {
            dtcrt.add(Restrictions.sqlRestriction("OwnerID in(select OwnerID from Orders group by " +
                            "OwnerID having sum(Total) >= ? and sum(Total) <= ?)", new Integer[]{clOrdsTtlPrcFrom, clOrdsTtlPrcTo},
                    new Type[]{StandardBasicTypes.INTEGER, StandardBasicTypes.INTEGER}));
            criteria.add(Subqueries.propertyIn("id", dtcrt));
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM