In Hibernate my issue can be solved using a filter, as explained here : https://stackoverflow.com/a/6920847/1966869. The xml version, which I have just tested and appears quite practical, is described here : http://www.mkyong.com/hibernate/hibernate-data-filter-example-xml-and-annotation/. There might be other solutions using @Where (How to use @Where in Hibernate) or @JoinFormula (@JoinFormula and @OneToMany definition - poor documentation), but I have not tested them.
Conditional/composite JoinColumn In JPA/Hibernate
-
14-04-2022 - |
Question
In one of my classes, say Location, I have something like this:
private List<Magician> magicians;
...
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name="location_id")
public List<Magician> getMagicians() {
return magicians;
}
public void setMagicians(List<Magician> magicians) {
this.magicians = magicians;
}
where Magician has variables
private Integer id;
private Integer location_id;
private Boolean active;
Now I would like to modify the getter annotation so as to get only the magicians for which active is true.
How can I achieve this?
Thanks for your attention.
Solution 3
OTHER TIPS
First of all, Magician should not have a location_id field. It should have a field of type Location. This would make a bidirectional association between the two entities:
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "location")
public List<Magician> getMagicians() {
return magicians;
}
...
@ManyToOne
@JoinColumn(name = "location_id")
public Location getLocation() {
return this.location;
}
Then, to answer your question, the state and associations of an entity are not used to implement a speciic use-case or query. Thy're used to model what the database contains. To get the active magicians of a given location, you should simply use a query:
select m from Magician m where m.active = true and m.location = :location
I wouldn't perform this work at the entity level, instead I would perform it using the EntityManager
to create a query. As JB mentions you need to add location as a composite object instead of an Integer.
//In Method
List<Magician> magicians =
em.createQuery("select m from Location l join Magician m where m.active = true and
l.[specify id here] = :locationId", Magician.class).setParameter("locationId",
1).getResultList();