# JPA downcast: criteria treat vs JPQL treat

**URL:** <https://discourse.hibernate.org/t/jpa-downcast-criteria-treat-vs-jpql-treat/2231>\
**Category:** Hibernate ORM\
**Created:** [February 6, 2019, 4:51pm UTC](https://discourse.hibernate.org/t/jpa-downcast-criteria-treat-vs-jpql-treat/2231 "2019-02-06T16:51:23Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hernan\_Keena](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/hernan_keena/32/1355_2.png) [@Hernan\_Keena](https://discourse.hibernate.org/u/Hernan_Keena)\
**Post date:** [February 6, 2019, 4:51pm UTC](https://discourse.hibernate.org/t/jpa-downcast-criteria-treat-vs-jpql-treat/2231/1 "2019-02-06T16:51:23Z")

</div>

I have a JPQL query that i had to transform to the criteria API. I used the criteria builder and got exactly the same results but the sql printed in the logs has an extra inner join.  
Am i using the criteria API the wrong way?. Or is this the expected behavior.

The data model is simple, its just an entity ‘Elemento’ with a property ‘datosElemento’ that is associated OneToOne with an entity ‘DatosElemento’ that uses Single Table Inheritance.

```auto
@Entity
public class Elemento<T extends DatosElemento>{
 ...
  @OneToOne(mappedBy = "elemento")
  public T getDatosElemento() {
    return datosElemento;
  }
 ...
}

@Entity
@Table(name = "datos_elemento")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "nombre")
public class DatosElemento {
 ...
}

```

I have created a test class with both queries to test the SQL generated by hibernate.

```auto

/* Original Query */
List<Elemento> elementosJPQL
        = entityManager.createQuery("From Elemento e Join e.datosElemento de Where Treat(de as DatosEquipo).marca='abc'")
                .getResultList();

System.out.println(elementosJPQL.size());

```

And i observe the following generated sql ( Just one inner join with datos\_elemento and it uses the discriminator column).

```auto
select
        elemento0_.id as id1_17_,
        elemento0_.descripcion as descripc2_17_,
        elemento0_.id_elementos as id_eleme7_17_,
        elemento0_.fecha_ingreso as fecha_in3_17_,
        elemento0_.identificacion as identifi4_17_,
        elemento0_.imagenes as imagenes5_17_,
        elemento0_.id_salida as id_salid8_17_,
        elemento0_.ubicacion as ubicacio6_17_ 
    from
        elemento elemento0_ 
    inner join
        datos_elemento datoseleme1_ 
            on elemento0_.id=datoseleme1_.id_elemento 
            and datoseleme1_.nombre='DatosEquipo' 
    left outer join
        datos_equipo datoseleme1_1_ 
            on datoseleme1_.id=datoseleme1_1_.id 
    where
        datoseleme1_1_.marca='abc'

```

Then i transformed the query with the criteria API

```auto
/* Transformed to Criteria */
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery query = cb.createQuery(Elemento.class);
Root from = query.from(Elemento.class);

Join datosElementoJoin = from.join("datosElemento", JoinType.LEFT);
Join datosElementoJoinTreated = cb.treat(datosElementoJoin, DatosEquipo.class);
Predicate p2 = cb.equal(datosElementoJoinTreated.get("marca"), "abc");

query = query.select(from).where(p2);

List<Elemento> elementosCriteria = entityManager.createQuery(query).getResultList();

System.out.println(elementosCriteria.size());

```

An here i observe several differences with the previous one as there is an extra inner join and the discrimator column is not used.

```auto
select
        elemento0_.id as id1_17_,
        elemento0_.descripcion as descripc2_17_,
        elemento0_.id_elementos as id_eleme7_17_,
        elemento0_.fecha_ingreso as fecha_in3_17_,
        elemento0_.identificacion as identifi4_17_,
        elemento0_.imagenes as imagenes5_17_,
        elemento0_.id_salida as id_salid8_17_,
        elemento0_.ubicacion as ubicacio6_17_ 
    from
        elemento elemento0_ 
    inner join
        datos_elemento datoseleme1_ 
            on elemento0_.id=datoseleme1_.id_elemento 
    inner join
        datos_elemento datoseleme2_ 
            on elemento0_.id=datoseleme2_.id_elemento 
    left outer join
        datos_equipo datoseleme2_1_ 
            on datoseleme2_.id=datoseleme2_1_.id 
    where
        datoseleme2_1_.marca=?

```

Again im learning to use the criteria API and i could be doing something the wrong way. So any help or ideas in this issue would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [February 6, 2019, 5:53pm UTC](https://discourse.hibernate.org/t/jpa-downcast-criteria-treat-vs-jpql-treat/2231/2 "2019-02-06T17:53:30Z")

</div>

The Criteria API query looks fine. I suppose this is a Hibernate issue.

Try to replicate it with [this test case template](http://in.relation.to/2016/01/14/hibernate-jpa-test-case-template/) and open a Jira issue for it.

---

<div class="post-metadata">

**Author:** ![ntam](https://avatars.discourse-cdn.com/v4/letter/n/a698b9/32.png) [@ntam](https://discourse.hibernate.org/u/ntam)\
**Post date:** [January 17, 2020, 11:01am UTC](https://discourse.hibernate.org/t/jpa-downcast-criteria-treat-vs-jpql-treat/2231/3 "2020-01-17T11:01:01Z")

</div>

Hi,  
Any news abou this?  
I’m also getting the same error (inner join instead of left outer join) when using CriteriaBuilder

regards,  
Nelson
