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...
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.
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.
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.
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));
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With