Given two entities:
CardPurchaseProductGroup, which has appg_statuscolumn (field named asstatuson the entity) that can be'A'(active) or'D'(deleted)
These conceptually have a many-to-many relationship but an explicitly defined join table entity named PurchaseProductGroupCard is used (so an external ID can be assigned for each mapping). So both Card and PurchaseProductGroup have a @OneToMany relationship to PurchaseProductGroupCard, e.g. in Card there is the following:
@OneToMany(mappedBy = "card")
private Set<PurchaseProductGroupCard> purchaseProductGroups;
This needs to be restricted so that purchaseProductGroups with a status of 'D' are excluded. One approach that seems to work is to put a @Where annotation just below the @OneToMany:
@Where(clause = "exists (select * from purchase_product_group ppg
where ppg.ppg_id = ppg_id AND ppg.ppg_status <> 'D')")
...But is there a better way to do this? Would ideally prefer Hibernate to join the tables and have a clause like "purchaseProduct.status <> 'D'").
I turned on SQL logging and examined the query output. For the above case it was this:
So the necessary join is already included and it looks like all that would be needed is this:
However, it turns out that doesn't work as Hibernate prepends the wrong table alias:
Unfortunately once an alias is assigned to a table, it isn't possible to use the original table name - so
purchase_product_group.ppg_status <> 'D'wouldn't work. And I'm not aware of a way to determine the alias name used by Hibernate programmatically - so at present the choice seems to be either hard-code the alias name that is found to be used by Hibernate (i.e.purchasepr1_.ppg_status <> 'D') or to use theexistsmethod described in the question.UPDATE: On further investigation it turns out that hard-coding the alias names isn't always workable. Here is a criteria query where this wouldn't work:
In the end I abandoned the
@Whereapproach and used@Filterinstead, which seems much better as it can accept HQL rather than database field names and when applied at the entity level will affect relationships (unlike@Where).