I want to use criteria to make the following query. I have an Entity with EmbeddedId defined:
@Entity @Table(name="TB_INTERFASES") public class Interfase implements Serializable { @EmbeddedId private InterfaseId id; } @Embeddable public class InterfaseId implements Serializable { @Column(name="CLASE") private String clase; }
And the criteria query that i am trying to do is:
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder(); CriteriaQuery<Interfase> criteriaQuery = criteriaBuilder.createQuery(Interfase.class); Root<Interfase> entity = criteriaQuery.from(Interfase.class); criteriaQuery.where( criteriaBuilder.equal(entity.get("clase"), "Clase"), );
But this is throwing an IllegalArgumentException:
java.lang.IllegalArgumentException: Not an managed type: class InterfaseId
i've tried with this queries too:
Root<Interfase> entity = criteriaQuery.from(Interfase.class); criteriaQuery.where( criteriaBuilder.equal(entity.get("id").get("clase"), "Clase"), );
and this one too...
Root<Interfase> entity = criteriaQuery.from(Interfase.class); criteriaQuery.where( criteriaBuilder.equal(entity.get("id.clase", "Clase"), );
with no luck. So my question is how can i make a query with criteria when my classes are using Embedded and EmbeddedId annotations?
Thanks!. Mauro.
The Criteria API is a predefined API used to define queries for entities. It is the alternative way of defining a JPQL query. These queries are type-safe, and portable and easy to modify by changing the syntax.
The EmbeddedId annotation is applied to a persistent field or property of an entity class or mapped superclass to denote a composite primary key that is an embeddable class. The embeddable class must be annotated as Embeddable .
In Hibernate, the Criteria API helps us build criteria query objects dynamically. Criteria is a another technique of data retrieval apart from HQL and native SQL queries. The primary advantage of the Criteria API is that it is intuitively designed to manipulate data without using any hard-coded SQL statements.
The use of @Id with a class marked as @Embeddable is the most natural approach. The @Embeddable tag can be used for non-primary key embeddable values anyway. It allows you to treat the compound primary key as a single property, and it permits the reuse of the @Embeddable class in other tables.
You need to use path navigation to access the attribute(s) of the Embeddable
. Here is an example from the JPA 2.0 specification (using the static metamodel):
6.5.5 Path Navigation
...
In the following example,
ContactInfo
is an embeddable class consisting of an address and set of phones.Phone
is an entity.CriteriaQuery<Vendor> q = cb.createQuery(Vendor.class); Root<Employee> emp = q.from(Employee.class); Join<ContactInfo, Phone> phone = emp.join(Employee_.contactInfo).join(ContactInfo_.phones); q.where(cb.equal(emp.get(Employee_.contactInfo) .get(ContactInfo_.address) .get(Address_.zipcode), "95054")) .select(phone.get(Phone_.vendor));
The following Java Persistence query language query is equivalent:
SELECT p.vendor FROM Employee e JOIN e.contactInfo.phones p WHERE e.contactInfo.address.zipcode = '95054'
So in your case, I think you'll need something like this:
criteriaBuilder.equal(entity.get("id").get("clase"), "Referencia 111")
Update: I've tested the provided entities with Hibernate EntityManager 3.5.6 and the following query:
CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<Interfase> criteria = builder.createQuery(Interfase.class); Root<Interfase> interfaseRoot = criteria.from(Interfase.class); criteria.select(interfaseRoot); criteria.where(builder.equal(interfaseRoot.get("id").get("clase"), "Referencia 111")); List<Interfase> interfases = em.createQuery(criteria).getResultList();
runs fine and generates the following SQL:
17:20:26.893 [main] DEBUG org.hibernate.SQL - select interfase0_.CLASE as CLASE31_ from TB_INTERFASES interfase0_ where interfase0_.CLASE=? 17:20:26.895 [main] TRACE org.hibernate.type.StringType - binding 'Referencia 111' to parameter: 1
Works as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With