【问题标题】:JPA Criteria query for a nested set嵌套集的 JPA 标准查询
【发布时间】:2018-11-14 23:35:32
【问题描述】:

我在该实体中有一个 Person 实体我有一组用于 PersonNames 的嵌套实体。 Person 和 PersonNames 之间存在 OneToMany 关系,因为一个人可以有多个名称。

    @XmlElementWrapper(name = "names")
    @XmlElement(name = "name")
    @OneToMany(mappedBy = "person", orphanRemoval = false, fetch = FetchType.EAGER)
    private Set<PersonNames> name;

您可以看到上面的 PersonNames 集是如何定义的。

我需要创建一个 JPA Criteria 查询来查找在 firstName、middleName 或 lastName 上具有 PersonNames 对象的所有 Person 实体。

public List<Person> getPerson(String lastName, String middleName, String firstName) {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Person> criteria = builder.createQuery(Person.class);

    Root<Person> root = criteria.from(Person.class);
    criteria.select(root);

    if(!lastName.isEmpty() && lastName != null) {
        Predicate lastNameCondition = builder.equal( root.get(Person_.personId).get(PersonNames_.lastName), lastName);
        criteria.where(lastNameCondition);
    }

    TypedQuery<Person> query = em.createQuery(criteria);
    return query.getResultList();
}

以上是我完成上述查询的尝试,但是我在 Predicate 行的“.get(Person_.personId)”部分收到以下错误:

类型Path中的get(SingularAttribute)方法不适用于参数(SingularAttribute)

谓词行可能完全错误,但我不知道如何实现这一点,而且我的谷歌似乎没有任何结果。我需要为此进行显式联接吗?

编辑:删除了 Hibernate 标签,因为我意识到这是我们的 Wildfly 服务器想要使用的,但我们没有在代码中使用 Hibernate。

【问题讨论】:

    标签: java jpa jaxb criteria-api


    【解决方案1】:

    Re:“不在我们的代码中使用 Hibernate API”——它已被弃用。

    CriteriaApi 有一些批评者,但无论如何,一旦你掌握了窍门,就可以很容易地接近它。

    @Entity
    public class Person {
        @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Long id;
    
        @OneToMany(mappedBy="person")
        private Set<PersonName> names;
    

    并填充它:

    tx.begin();
    Person p = new Person();
    PersonName c1 = new PersonName(p, "F1", "M1", "L1"); 
    PersonName c2 = new PersonName(p, "F2", "M2", "L2"); 
    em.persist(p);
    em.persist(c1);
    em.persist(c2);
    tx.commit();
    

    并查询它

    em.clear();
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Person> query = cb.createQuery(Person.class);
    Root<Person> person = query.from(Person.class);
    Join<Person, PersonName> names = person.join("names");
    Predicate[] findNames = new Predicate[3]; 
    findNames[0] = cb.equal(names.get("firstName"), "F1");
    findNames[1] = cb.equal(names.get("middleName"), "M1");
    findNames[2] = cb.equal(names.get("lastName"), "L1");
    query.where(findNames);
    List<Person> persons = em.createQuery(query).getResultList();
    System.out.println(persons);
    

    【讨论】:

    【解决方案2】:

    这行得通吗?

    Criteria c = s.createCriteria(Person.class);
    c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    c.createAlias("name", "name");
    c.add(Restrictions.eq("name.lastName", lastName));
    return c.list();
    

    【讨论】:

    • 可能,但我是个白痴,并意识到我们的 Wildfly 服务器想要使用 Hibernate,因此我想到了它,但我们没有在我们的代码中使用 Hibernate API(如果我们可以找不到准系统的 JPA Criteria 方法)。
    猜你喜欢
    • 1970-01-01
    • 2014-09-07
    • 2016-05-23
    • 1970-01-01
    • 2012-04-01
    • 2014-02-15
    • 1970-01-01
    • 2011-06-19
    • 1970-01-01
    相关资源
    最近更新 更多