5

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)

1
  • I have the same problem and I can confirm the loading by id will not use filters, use queries. If you had more info on why it is so, it would be great. Also by loading by id we mean session.get(Entity.class, id), right? Commented Aug 19, 2015 at 8:35

1 Answer 1

7

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.

Sign up to request clarification or add additional context in comments.

2 Comments

'1<>0' is just used to show a trivial condition. You'are right, bad idea :)
"For this reason, you could use Hibernate @Where" - Depends on whether he needs to activate/deactivate on convinience

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.