What we're trying to achieve?
Spring Data JPA lets us define repository methods like this:
Optional<User> findByEmail(String email);
With that, the query to be run will be figured out with the method name. In this case, something like select * from user where email = ?.
We want to apply an additional common criteria to all such find...By methods on the repository, a and deleted_at is null condition.
Essentially, findByEmail should behave like findByEmailAndDeletedAtNull.
Why?
We used to do this with reactive Spring Data MongoDB by extending ReactivePartTreeMongoQuery, and overriding createQuery with something like this:
@Override
protected Mono<Query> createQuery(ConvertingParameterAccessor accessor) {
return super.createQuery(accessor).map(query -> {
query.addCriteria(where("deletedAt").is(null));
return query;
});
}
This worked well. We're now moving to using an RDBMS and looking for similar behavior there.
What have we tried?
I found that PartTreeJpaQuery.QueryPreparer.createQuery() is the one that calls EntityManager.createQuery off a CriteriaQuery object, and returns a TypedQuery object.
I managed to hook into the middle of this But can't add additional conditions to the TypedQuery object, like I can with CriteriaQuery. And there's no way to access the QueryPreparer object either to hook into it.
I can't extend PartTreeJpaQuery class either, because it doesn't have any public constructors.
Is there any way to do this at all?
Try
And call it using
Another approach is to use a Discriminator to differ between two Entities:
See here how to do that.