16

does anyone know if and how the solution for following question (which is written in the JPA API) can be written using the hibernate criteria API?

To be more specific I have a Discussion entity that contains a list of participants (which is a list of usernames):

@ElementCollection
@Column(name = "user_name")
@CollectionTable(name = "DISCUSSION_USER", joinColumns = @JoinColumn(name = "DISCUSSION_ID"))
@OrderColumn(name = "ORDER_INDEX")
private List<String> participants = new ArrayList<String>();

Now I need to retrieve all Discussions where a given username is a participant.

If I would have created an entity for Participant this would be straightforward:

    Criteria crit = getSession().createCriteria(Discussion.class);
    crit.createAlias("participants", "p");
    crit.add(Restrictions.eq("p.userName", portalUsername));

But I can't create an alias with a non entity...

Community
  • 1
  • 1
Stijn Geukens
  • 15,454
  • 8
  • 66
  • 101

3 Answers3

34

Late answer.

The correct propertyName for collection (annotated by @ElementCollection) is "elements" or constant CollectionPropertyNames#COLLECTION_ELEMENTS.

Try with the following answers

Criteria crit = getSession().createCriteria(Discussion.class);
crit.createAlias("participants", "p");

crit.add(Restrictions.eq("p.elements", portalUsername));

or use the constant COLLECTION_ELEMENTS instead

crit.add(Restrictions.eq("p." + CollectionPropertyNames.COLLECTION_ELEMENTS, portalUsername));
lschin
  • 6,745
  • 2
  • 38
  • 52
2

As explained here what I wanted is not possible:

The limitations of using an ElementCollection instead of a OneToMany is that the target objects cannot be queried, persisted, merged independently of their parent object. They are strictly privately-owned (dependent) objects, the same as an Embedded mapping. There is no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent.

So, I used a OneToMany instead.

Stijn Geukens
  • 15,454
  • 8
  • 66
  • 101
1

Can you give us a more complete schema and query?

Also, Criteria API sucks. Try using QueryDSL, your query might look like:

HibernateQuery q=new HibernateQuery(getSession())
.from(QDiscussion.discussion).from(QDocument.document)
.where(QDocument.document.userName.in(QDiscussion.discussion.userNames))
.list(QDocument.document);
Cyberax
  • 1,667
  • 16
  • 18