嵌套集的JPA条件查询

时间:2018-11-14 23:35:32

标签: java jpa jaxb criteria-api

我在该实体内有一个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();
}

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

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

谓词行可能是完全错误的,但是我不能全神贯注于如何完成此操作,而且我在Google上似乎没有发现任何结果。我需要为此进行显式联接吗?

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

2 个答案:

答案 0 :(得分:1)

回复:“我们的代码中未使用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);

答案 1 :(得分:0)

这项工作可以吗?

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();