@Where does not apply to composite id cases

I have a use case that involves composite ids to join multiple tables. I would like to use the @Where annotation to exclude [soft] deleted entities. However, Hibernate is not adding it to the joins.

This is my entity spec:

@Entity
@Data
@Table(name = "_Who")
public class Who {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @OneToMany(mappedBy = "who")
    Set<WhoWhatWhere> storage;
}

@Entity
@Data
@Table(name = "_What")
public class What {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String thing;
}

@Entity
@Data
@Table(name = "_Where")
public class Where {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String place;
    private Boolean deleted
}

@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Entity
@NoArgsConstructor
@Table(name = "_WhoWhatWhere")
public class WhoWhatWhere {
    public WhoWhatWhere(Who who, What what, Where where) {
        this.who = who;
        this.what = what;
        this.where = where;
        this.setId(new WhoWhatWhereId(who.getId(), what.getId(), where.getId()));
    }

    @EmbeddedId
    WhoWhatWhereId id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "who_id", insertable = false, updatable = false)
    private Who who;

    @ManyToOne
    @JoinColumn(name = "what_id", insertable = false, updatable = false)
    private What what;

    @ManyToOne
    @JoinColumn(name = "where_id", insertable = false, updatable = false)
    @Where(clause = "deleted = false")
    private Where where;
}

@Embeddable
@NoArgsConstructor
public class WhoWhatWhereId implements Serializable {
    public WhoWhatWhereId(Long whoId, Long whatId, Long whereId) {
        this.whoId = whoId;
        this.whatId = whatId;
        this.whereId = whereId;
    }

    @Column(name = "who_id")
    Long whoId;
    @Column(name = "what_id")
    Long whatId;
    @Column(name = "where_id")
    Long whereId;

}

I’d expect the @Where to exclude any What that has deleted=true, however, when I select for all the Whos, it returns all the linked objects regardless of that property value. Adding the annotation to the What class definition does not work either because the entities are pulled in with a join, not queried directly. Also, the @WhereJoinTable is not applicable here, because I’m not trying to filter on a column (property) found on the join table.

How can I achieve this functionality?

The @Where annotation is only supported on the entity level and for plural attributes.

Yes, but it must be narrower than that, because I tried it on the entity level…

@Where(clause = "deleted=false")
public class Where {...}

… this did not work, I presume because there were already records in the composite key table.

I also tried it on the plural attribute…

public class Who {
    ...
    @OneToMany(mappedBy = "who")
    @Where(clause = "deleted=false")
    Set<WhoWhatWhere> storage;
}

… this also did not work, I presume because it was attempting to apply the condition to the WhoWhatWhere class, which does not have the deleted field.

Also worth noting is that in neither case was where syntax added to the query.

What do you mean by “this did not work”? We have a bunch of tests that clearly show that this works. So whatever your special case that does not work, you will have to give me more details. Are you sure you updated Hibernate to the latest version 5.4.31.Final? If so, and you still have the problem, please create an issue in the issue tracker(https://hibernate.atlassian.net) with a test case(https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-5/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java) that reproduces the issue.