Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ElementCollection createAlias in hibernate API

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

like image 766
Stijn Geukens Avatar asked Feb 02 '11 10:02

Stijn Geukens


People also ask

What is the use of createAlias in hibernate?

createAlias. Join an association using the specified join-type, assigning an alias to the joined association. The joinType is expected to be one of CriteriaSpecification.

How can we join multiple tables in hibernate criteria?

Criteria in Hibernate can be used for join queries by joining multiple tables, useful methods for Hibernate criteria join are createAlias(), setFetchMode() and setProjection() Criteria in Hibernate API can be used for fetching results with conditions, useful methods are add() where we can add Restrictions.

What is criteria in Java?

The Criteria API is used to define queries for entities and their persistent state by creating query-defining objects. Criteria queries are written using Java programming language APIs, are typesafe, and are portable.


2 Answers

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));
like image 56
lschin Avatar answered Sep 21 '22 08:09

lschin


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.

like image 38
Stijn Geukens Avatar answered Sep 20 '22 08:09

Stijn Geukens