JPA - Criteria API and EmbeddedId

前端 未结 3 1831
陌清茗
陌清茗 2020-12-05 13:24

I want to use criteria to make the following query. I have an Entity with EmbeddedId defined:

 @Entity
 @Table(name=\"TB_IN         


        
相关标签:
3条回答
  • 2020-12-05 13:53

    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.

    0 讨论(0)
  • 2020-12-05 14:02

    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();
    
    0 讨论(0)
  • 2020-12-05 14:06

    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.

    0 讨论(0)
提交回复
热议问题