ElementCollection createAlias in hibernate API
Asked Answered
H

3

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...

Housecoat answered 2/2, 2011 at 10:4 Comment(0)
H
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.

Housecoat answered 2/3, 2011 at 8:11 Comment(0)
L
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));
Latham answered 17/5, 2012 at 14:49 Comment(5)
never too late for a good answer, I'll be sure to try this out onceHousecoat
Sorry didn't work... dammit.... But I'm using a very old release, may be this is fixed in the newer versions..Chidester
It seems from the usage of these constants in Hibernate source code, these are for HQL queries only.Melpomene
You can do this in Hibernate 4, not Hibernate 3, I guessTrilly
Even a late answer is useful to others nearly 10 years after it was given. Thank you!Waftage
H
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.

Housecoat answered 2/3, 2011 at 8:11 Comment(0)
P
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);
Peerless answered 21/2, 2011 at 23:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.