2

I have a pretty complex criteria, which I use to retrieve, sort and page server-side data. I stripped down the following excerpt:

    // create criteria over a bunch of tables...
    Criteria testCriteria = getSession().createCriteria(PriceRequest.class)
            .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
            .setFetchMode("pricedBy", FetchMode.JOIN)
            .setFetchMode("canceledBy", FetchMode.JOIN)
            .setFetchMode("product", FetchMode.JOIN)
            .setFetchMode("product.underlyings", FetchMode.JOIN)
            .setFetchMode("product.tradedBy", FetchMode.JOIN)
            .setFetchMode("product.requestedBy", FetchMode.JOIN)
            .setFetchMode("fileUploads", FetchMode.JOIN);

    // add various filter fields (only if required in real code)...
        Criteria subCriteria = testCriteria
                .createCriteria("product", JoinFragment.LEFT_OUTER_JOIN)
                .setFetchMode("underlyings", FetchMode.JOIN)
                .add(Restrictions.ge("maturityDate", new Date()));

        testCriteria.addOrder(Order.desc("product.id")); // (1)
        testCriteria.addOrder(Order.desc("product.maturityDate")); // (2)

        List list = testCriteria.list();

Statement (1) runs fine, statement (2) ends with the following exception:

SEVERE: Servlet.service() for servlet rest threw exception org.hibernate.QueryException: could not resolve property: product.maturityDate of: com.my.model.PriceRequest

I picked "maturityDate" as an example, but I'm having this issues with all product properties except "product.id".

I also tried adding an alias for product ("prod"). This allows to sort by maturity date ("prod.maturityDate"), but fails on adding the restriction to subcriteria.

I so much have no clue what's going wrong...

Mikko Maunu
  • 41,366
  • 10
  • 132
  • 135
Jan Groth
  • 14,039
  • 5
  • 40
  • 55

1 Answers1

2

createCriteria(association) does not create an alias but you need one for the orderby

Also you cant filter on an association and eager fetch it because you might filter out entities of the association which are needed to initialize it hence the fetchmode is ignored. Use a correlated subquery

// create criteria over a bunch of tables...
Criteria testCriteria = getSession().createCriteria(PriceRequest.class)
        .setFetchMode("pricedBy", FetchMode.JOIN)
        .setFetchMode("canceledBy", FetchMode.JOIN)
        .createAlias("product", "prod")
        .setFetchMode("prod.underlyings", FetchMode.JOIN)
        .setFetchMode("prod.tradedBy", FetchMode.JOIN)
        .setFetchMode("prod.requestedBy", FetchMode.JOIN)
        .setFetchMode("fileUploads", FetchMode.JOIN)
        .addOrder(Order.desc("prod.maturityDate"));       // (2)

// add various filter fields (only if required in real code)...
if (...)
{
    Criteria subCriteria = getSession().createCriteria(PriceRequest.class)
        .createCriteria("product", JoinFragment.LEFT_OUTER_JOIN)
        .add(Restrictions.ge("maturityDate", new Date()));
        .setResultTransformer(Projection.id)

    testCriteria = testCriteria
        .add(Subqueries.PropertyIn("id", subCriteria));
        .setFetchMode("underlyings", FetchMode.JOIN)
}

List list = testCriteria.list();
Firo
  • 30,626
  • 4
  • 55
  • 94
  • @Fito, can you take a look in this SO: http://stackoverflow.com/questions/25841292/hibernate-fetching-in-criteria-ignored – vlio20 Sep 19 '14 at 18:53