JPA - Criteria API and EmbeddedId

三世轮回 提交于 2019-11-27 21:08:52

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")

References

  • JPA 2.0 Specification
    • Section 6.5.5 "Path Navigation"

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.

It is an old question, but anyway...

Another extremely simple solution is

InterfaseId id = new InterfaseId();
id.setClase("Clase");
Interfase found = em.find(id);

Except if you trying to do something else besides what you asked, this is the "sane" way to do it. A query on the id will return maximum one result.

MicroCharles

Try to copy and paste the metamodel classes into the same folder where your entities are saved (in NetBeans 8.2 they are automatically generated and have the same name of your entity but with an underscore at the end. Should be something like Interfase_ and InterfaseId_).

Force the import of the metamodel classes Interfase_ and InterfaseId_ and refer to the desired field.

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(Interfase_.id).get(InterfaseId_.clase),"Referencia 111"));
List<Interfase> interfases = em.createQuery(criteria).getResultList();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!