在 JPA2 中替代传统 Hibernate 的特殊 属性 "elements"

Alternative to legacy Hibernate's special property "elements" in JPA2

Hibernate 处理查询基本值的集合,如 Hibernate User Guide, Chapter 30. Legacy Hibernate Criteria Queries, Section 30.8 Collections 中所述。

When using criteria against collections, there are two distinct cases. One is if the collection contains entities <...>, and the second is if the collection contains scalar values <...>. In the first case <...> we create a Criteria object against the collection property and restrict the entity or component properties using that instance.

For querying a collection of basic values, we still create the Criteria object against the collection, but to reference the value, we use the special property "elements".

现在,由于 Hibernate 的 API 的这一部分已被弃用,我想使用 JPA 2.0(或更高版本)CriteriaQuery API 重新编写我的 getChildren() 方法。 (实体 class 已经使用 javax.persistence 包中的注释重写。)

标准 JPA 中是否已经存在 Hibernate 特殊 属性“元素”的替代品?

package com.abc.model;
import java.util.*;
import javax.persistence.*;
@Entity()
@Table(name = "Group", uniqueConstraints = { 
          @UniqueConstraint(columnNames = { "Id" } ) })
public class Group {

    @Column(name = "Id")
    @Basic()
    @Id()
    private String id;

    @Column(name = "ParentId")
    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(name = "GroupParentIds",
      joinColumns = { @JoinColumn(name = "GroupId") })
    private Set<String> parentIds = new HashSet<>();

    String getId() { return id; }
}

import com.abc.model.Group;
import org.hibernate.*;
public class GroupManager {
    List<Group> getChildren(Session session, Group group) {
        return session.createCriteria(Group.class)
          .createCriteria("parentIds")
          .add(Restrictions.eq("elements", group.getId()))
          .list();
    }
}

我还没有找到任何替代旧版 属性 的方法。但是,在我的案例中有一个很好的解决方法。

我添加了一个使用显式连接的谓词 parentIds:

List<Group> getChildren(Group g) {
    CriteriaBuilder b = getEntityManager().getCriteriaBuilder();
    CriteriaQuery q = b.createQuery();
    Root r = q.from(Group.class);
    q.select(r.get("name"));
    Predicate p = r.join("parentIds").in(g.getId());
    q.where(p);
    List<Group> result = getEntityManager().createQuery(q).getResultList();
    return result;
}