'Hibernate - Retrieve parent + childrens that matches specific criterias
I'm working on a project where Hibernate criterias are still in use. Here is a quick overview of the entities that we're using :
public class Location {
[...]
@OneToMany(mappedBy = "location")
private Set<EventLocation> eventLocations = new HashSet<>();
public class EventLocation {
[...]
@ManyToOne(optional = false, cascade = CascadeType.PERSIST)
@JoinColumn(name = "event_id")
private Event event;
@ManyToOne(optional = false, cascade = CascadeType.PERSIST)
@JoinColumn(name = "location_id")
private Location location;
public class Event {
[...]
@OneToMany(mappedBy = "event", cascade = CascadeType.ALL)
private Set<EventLocation> locations = new HashSet<>();
@OneToMany(mappedBy = "event", cascade = CascadeType.ALL)
private Set<EventTag> tags = new HashSet<>();
public class EventTag {
[...]
@ManyToOne(optional = false, cascade = CascadeType.PERSIST)
@JoinColumn(name = "event_id")
private Event event;
@ManyToOne(optional = false, cascade = CascadeType.PERSIST)
@JoinColumn(name = "tag_id")
private Tag tag;
public class Tag {
[...]
@OneToMany(mappedBy = "tag")
private Set<EventTag> eventTags = new HashSet<>();
I wonder if we have a way, using Hibernate Criteria API, to retrieve a list of Location which holds a filtered list of Event objects ?
For example, we'd like to have a query that would return a location but the eventLocations would only contains results if eventLocations.event.type = "SAMPLE_TYPE" AND eventLocations.event.tags.id IN (1,2,3).
We tried using this, but the eventLocation set contains objects that should have been filtered out.
var crit = getSession().createCriteria(Location.class, "loc");
crit.createAlias("loc.eventLocations", "eloc");
crit.createAlias("eloc.event", "event");
crit.createAlias("event.tags", "etags");
crit.createAlias("etags.tag", "tag");
crit.add(Restrictions.in("etags.id", Arrays.asList(1, 2, 3)));
crit.add(Restrictions.eq("event.type", "SAMPLE_TYPE"));
var locations = crit.list();
Generated query looks like that when I enable Hibernate statistics :
select
[...]
from
location LOC
inner join
event_location ELOC on LOC.id=ELOC.id_location
inner join
event EVENT ON ELOC.id_event=EVENT.id
inner join
event_tag ETAG ON EVENT.id=ETAG.event_id
inner join
tag TAG ON ETAG.id_tag=TAG.id
where
EVENT.type="SAMPLE_TYPE
AND TAG.id in (
1, 2, 3
)
This request runs fine if I run it using PgAdmin, but when using Hibernate directly, it seems like when I loop through locations.eventLocations, it contains eventlocation for events that should have been filtered out because they don't match the "SAMPLE_TYPE" type.
EDIT It looks like this post asks for the same sub-filtering feature, but to this date no answer was provided. I faced the same behavior mentioned in Steven Francolla's comment (using direct child query returns only matching children's, but when I try to do child-child filtering I doesn't seems to work).
I'm still linking to this post because it explains the problem we're facing with a lot of added details.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
