0
votes

Hibernate handles querying a collection of basic values as described in 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".

Now as this part of Hibernate's API has become deprecated, I would like to re-write my getChildren() method using the JPA 2.0 (or higher) CriteriaQuery API. (The entity class is already re-written using the annotations from javax.persistence package.)

Is there an alternative to the Hibernate's special property "elements" in the standard JPA already?

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

1 Answers

0
votes

I haven't found any alternative to the legacy property. However, there's a nice workaround in my case.

I added a Predicate that uses an explicitly joined 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;
}