Predicates created with different sessions cause generatedalias0 and generatedalias1

Have a problem in Hibernate 5.6:

I create a predicate through a DAO:


 public Predicate getPredicatesForRfqSearch() {
		final Session session = this.getSession();

		CriteriaBuilder cb = session.getCriteriaBuilder();
		CriteriaQuery cq = cb.createQuery(aliasToBeanClass); // EproQuoteBVOImpl.class

		Root root = cq.from(aliasToBeanClass);

		return cb.or(
				cb.and(
						cb.greaterThanOrEqualTo(root.get(EproQuoteBVO.RFQ_START_DATE_OF_RFQ), new Date(new Date().getTime() - (12 * 60l * 60l * 1000l))),
						cb.equal(root.get(EproQuoteBVO.RFQ_NATURE), EproRfqBVO.NATURE_SPOT)
				),
				cb.and(
						cb.greaterThanOrEqualTo(root.get(EproQuoteBVO.RFQ_START_DATE_OF_RFQ), new Date(new Date().getTime() - (120 * 60l * 60l * 1000l))),
						cb.equal(root.get(EproQuoteBVO.RFQ_NATURE), EproRfqBVO.NATURE_RFQ)
				)
		);
    }

After that, I pass the predicate (in a hashmap/criteriaMap) to another generic DAO where more predicates are added and the query is being executed.

public List<ENTITY> findByCriteria(final Map<String, Object> criteriaMap, final List<String> fields, final Class<ENTITY> entityClass, boolean detached, List<String> collectionsToInitialize) {
		final Session session = this.getSession();

		CriteriaBuilder cb = session.getCriteriaBuilder();
         CriteriaQuery cq = cb.createQuery(aliasToBeanClass); // EproQuoteBVOImpl.class

              // More predicates are added...
             // query is executed
}

Unfortunately, because the predicates are created within two different sessions, Hibernate is translating it using two different generatedAlias although all predicates in that hashmap target the same table.

SELECT   generatedalias0
FROM     com.myapp.quote.business.object.quotebvoimpl AS generatedalias0
WHERE    (
                  generatedalias0.archived=:param0 )
AND      (
                  generatedalias0.supplierid=1189l )
AND      ( ( (
                                    generatedalias1.rfqstartdateofrfq>=:param1 )
                  AND      (
                                    generatedalias1.rfqnature=:param2 ) )
         OR       ( (
                                    generatedalias1.rfqstartdateofrfq>=:param3 )
                  AND      (
                                    generatedalias1.rfqnature=:param4 ) ) )
AND      ( (
                           lower(generatedalias0.supplierquotestatus) LIKE :param5 )
         OR       (
                           lower(generatedalias0.supplierquotestatus) LIKE :param6 ) )
AND      (
                  generatedalias0.rfqenddateofrfq>=:param7 )
AND      ( (
                           generatedalias0.owner=:param8 )
         OR       (
                           generatedalias0.owner=:param9 ) )
ORDER BY generatedalias0.rfqstartdateofrfq DESC]

The query with generatedalias1 was created in another session / with another criteriaBuilder instance than the part that uses generatedalias0.

Is there anything that can be done here?

The solution was to set the same alias root.alias("myAlias"); at the two occasions where the predicate are generated that are supposed to be executed within the same query.

That’s not safe and will break with Hibernate 6. You have to rebuild the predicate with the Root/Join/From elements of the new query.

That was what I’ve tried first. I tried to “overwrite” some parts of the Predicate with the same root object that I use but I failed miserably. Do you have any examples or additional hints how I can extract the information necessary from existing Predicates?

Just pass around an object which can create the predicate on demand based on CriteriaBuilder, CriteriaQuery and Root. That’s the simplest solution. Then you can just rebuild the predicate for a new root.

1 Like