1
votes

First off, I am maintaining some code that I didn't write and I'm fairly new to Java and Hibernate. I recently tweaked a query that runs in a Hibernate session. The return type didn't change (it remains a List) but I changed the query from session.createquery to session.createSQLquery. For some reason, that broke the code that consumes the return List.

Here is the consuming method:

public void getStuff(CompanyDAO company, ProductDAO dao, Long listingId, Long year, Long prodId, String startTag, String endAdFileTag, String letter) throws DAOException {
        List<Object[]> Products = dao.loadStuff(year, prodId, listingId, letter);

        if (Products != null && Products.size() > 0) {
            for (Object[] p : Products) {
                if (p != null) {
                    ProductListing parentChild = (ProductListing) p[0];
                    Long childCountObj = (Long) p[1];
                    int childCount = childCountObj.intValue();

                    if (parentChild != null) {
                        parentChild.setNextLevelChildrenCount(childCount);
                     }
                }
            }
        }
    } 

It's the enhanced for loop ( for (Object[] p : Products) { ) that is causing the exception.

Here's the exception: java.lang.ClassCastException: ProductListing cannot be cast to [Ljava.lang.Object;

I don't understand why changing the query would break this code. The query is returning an array of objects just as it had before the tweak.

I'd appreciate any insight at all into this puzzlement.

Thanks.

DAO before:
public List loadStuff(Long year, Long prodId, Long listingId, String letter) throws DAOException { Session session = HibernateUtil.getSession(HibernateUtil.keys[sessionId]); StringBuffer strQuery = new StringBuffer(); if (year == null || prodId == null || listingId == null ) return null;

    logger.debug("prodCode = " + prodId);
    logger.debug("year = " + year);


    strQuery.append("select pl, (select count(*) from ProductListing pppl where pppl.listingId = :listingid ");
    strQuery.append(" and pppl.responseYear = :year and pppl.parentProductId = pl.productId) as CHILD_COUNT ");
    strQuery.append(" from ProductListing pl ");
    strQuery.append(" where pl.parentProductId = :prodid ");
    strQuery.append(" and pl.responseYear = :year ");
    strQuery.append(" and pl.listingId = :listingid ");

    strQuery.append(" and (exists(select 0 from ProductListingMain plm, PdMain pm ");
    strQuery.append(" where plm.productListingId = pl.id ");
    strQuery.append(" and pm.currentVersionId = plm.versionId ");
    strQuery.append(" and pm.responded = 'Y' ");
    strQuery.append(" and pm.deleteFlag = 'N' ");
    strQuery.append(" and pm.onlineFlag = 'Y') ");
    strQuery.append(" or exists(select 0 from ProductListing ppl ");
    strQuery.append(" where ppl.listingId = :listingid ");
    strQuery.append(" and ppl.responseYear = :year ");
    strQuery.append(" and ppl.parentProductId = pl.productId)) ");

    //todo iclude the param letter in the query ... please test it before implementing
    if (letter != null) strQuery.append(" and upper (pl.onlineDescription) like '" + letter + "%' ");

    Query query = session.createQuery(strQuery.toString())
            .setLong("year", year)
            .setLong("prodid", prodId)
            .setLong("listingid", listingId);

    List list = query.list();
    return list;
}  
DAO after:  

public List loadStuff(Long year, Long prodId, Long listingId, String letter) throws DAOException { Session session = HibernateUtil.getSession(HibernateUtil.keys[sessionId]); StringBuffer strQuery = new StringBuffer(); if (year == null || prodId == null || listingId == null ) return null;

   String letterClause;
   if (letter != null) 
      letterClause = " and upper (pl.onlineDescription) like '" + letter + "%'  \n";
   else
      letterClause = " ";

   strQuery.append(
   " select pl.* \n" + 
   " from PRODUCT_LINE p, PRODUCT_LINE_X_LISTING pll, \n" + 
   "  PRODUCT_X_LISTING pl, CURRENT_YEAR cy, \n" + 
   "  LISTING l \n" + 
   " where p.id = pll.PRODUCT_LINE_ID \n" + 
   "  and p.prod_line_no = cy.PROD_LINE_MASTER  \n" +
   "  and pl.RESPONSE_YEAR = cy.ONLINE_YEAR \n" + 
   "  and pl.LISTING_ID = cy.LISTING_ID \n" + 
   "  and pll.LISTING_ID = l.id \n" + 
   "  and cy.LISTING_ID = l.id \n" + 
   "  and pll.YEAR = cy.ONLINE_YEAR \n" + 
   "  and p.Id = pll.product_line_id \n" + 
   "  and pl.PARENT_PRODUCT_ID = " + prodId + 
   "  and pl.LISTING_ID = " + listingId +
   "  and exists \n" +
           "   (select 'x' \n" + 
           "   from pd_product_listing_mv mv \n" +
           "   where mv.listing_id = pl.listing_id \n" +
           "     and mv.id = pl.id) \n" +
     letterClause +
   " order by upper(pl.ONLINE_DESCRIPTION) ");

    Query query = session.createSQLQuery(strQuery.toString())
     // return all columns in the ProductListing table, i.e. the entire class
       .addEntity("pl", com.acme.run.model.directories.ProductListing.class);
    List list = query.list();

    return list;
}

Sorry this isn't formatted better. This is my first post and

2
Show your ProductDAO interface.duffymo
Where's the query? Actually, the whole loadStuff() method.Nicolae Albu

2 Answers

2
votes

You are selecting only pl.* and you are using addEntity("pl", ProductListing.class), so the returned List is of objects of type ProductListing. The old query was selecting a CHILD_COUNT also, but not anymore. I presume you forgot the COUNT value in the new query.

0
votes

It looks like changing your query from "createquery" to createsqlquery" resulted in Hiberate returning you a List of ProductListing objects instead of List

Hard to tell without looking at the ProductDAO -- the older and the newer versions.