I'm using JPA with Hibernate as a JPA provider. I cannot figure out how to configure my entities to apply a hibernate filter to a One-to-Many association.
I have a Master
with a collection of Details
. Here are my entity definitions:
@Entity
public class Master extends Base {
private List<Detail> details;
@OneToMany
@OrderColumn
@JoinTable(name = "master_details")
@Filter(name = "notDeleted")
// @Where(clause = "deleted = 'false'")
public List<Detail> getDetails() {
return details;
}
public void setDetails(List<Detail> details) {
this.details = details;
}
}
@Entity
@FilterDef(name = "notDeleted", defaultCondition = "deleted = false")
public class Detail extends Base {
private Boolean deleted = false;
public Boolean getDeleted() {
return deleted;
}
public void setDeleted(Boolean deleted) {
this.deleted = deleted;
}
}
The Base
is nothing special but a simple MappedSuperClass
:
@MappedSuperclass
public class Base {
private Long id;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
When loading a Master
by entityManager.find(Master.class, mid)
, the filter should prvent all Details
from loading but I checked the sql queries generated by hibernate (by show_sql=true
) and no where clause is added when loading details of the master !!! A sample query generated by hibernate is:
select
details0_.Master_id as Master1_6_1_,
details0_.details_id as details2_1_,
details0_.details_ORDER as details3_1_,
detail1_.id as id7_0_,
detail1_.deleted as deleted7_0_,
from
master_details details0_
inner join
Detail detail1_
on details0_.details_id=detail1_.id
where
details0_.Master_id=?
After some search there was some hints that "loading by id will not use filters, use queries" so I tried the following but no gain :(
entityManager.createQuery("from Master where id=" + mid).getSingleResult();
But just if the @Where
above getDetails is uncommented (instead of @Filter
), its clause is added to the query generated by hibernate (but I cannot use @Where
)
The Hibernate @Filter
needs to be manually activated via enableFilter
method:
session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");
However, filters are useful when you need to parameterize the filtering condition. And, you don't seem to need a dynamic filtering clause.
For this reason, you could use the Hibernate @Where
filter, like this:
@org.hibernate.annotations.Where(clause="deleted=false")
public List<Detail> getDetails() {
return details;
}
This way, you should get the list of non-deleted Detail
entities.
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