findById - Can we have the option to filter on "_class" for findById(ID id) implicitly

Hi,
I am trying to figure out whether, is there any annotation or a way to restrict the documents which are of specific class type when using findById method querying by passing Id of the document.
Situation: Assume, there are class A and class B which extends A. While saving into couch, we could be able to save as class B but when we are trying to get using findById in different context where class A is relevant, its fetching the document which is of type B and mapping it to class A by mutating and thereby causing data inconsistency.
Do we have any implicit way to restrict on class while querying with findById method? Any help/suggestions would be really appreciated. Thanks!!

Just to be clear, findById() is from Spring Data, right?

Assuming yes, @davidkelly can probably help.

Yes, it is from Spring Data.

I believe one way that should work would be to have a repository for A, and a repository for B. Then, just use the appropriate repo. However, when you save with repo A, the _class will be written as the full class path to A, similarly for B. So if you want to save as B, then later update as A, this probably will not work.

I think maybe you could get your A as a projection, however. Checkout https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/#couchbase.repository.n1ql - the section on DTO Projections. That will give you a way to return an A, at least. But perhaps you’d want to do something clever to accept an A in a method in your repo (along with an id, etc…) and update the B.

I have the same problem. @davidkelly Both class A and B have their own repositories i.e. aRepo and bRepo. If I do a aRepo.findById(bId) it will map the B class instead of giving me and empty optional result.

@hari added my own findById function that filters on the class:

@Query("#{#n1ql.selectEntity} WHERE META(#{#n1ql.bucket}).id = $1 AND #{#n1ql.filter}")
Optional<A> findByIdFilter(String id);

I do not want to override the findById() function as that still has purpose. With the findByIdFilter I need an index on _class and id.

Would be helpful we can specify that as some sort of annotation.

This is worth bringing up in the spring data couchbase Jira. I don’t see why that couldn’t be a small feature request - when you have a bucket with 2 classes in it, and the findById is given a class A id but called on a the classB repo, the ‘expectation’ isn’t really clear. One could want the object coerced into the type for that repo, or not.

In my mind, the latter (what you did) is what one would expect. But it could be either I suppose. So – I think it is worth making an issue for it, and seeing how the discussion goes. You can start here to create an issue.

@lukekroon, i have implemented exactly in the same way with n1ql query. And yes, index on id and _class is absolutely needed.

@davidkelly - Seems to be good idea though. Lets create an issue in their board. Thanks.
Would you be helping us in creating one?

@hari - best if you or @lukekroon creates it so we know it is an issue a real user would like to see implemented. You could also make an issue in GitHub for it but I think the Jira is best as it it really tracked in there. LMK if you run into issues creating it.

I went through the issues on Jira and found this one, which is the same problem we have.

there is also a problem with deleteById(id). If you have ClassA / ClassARepo and ClassB / ClassBRepo and call ClassBRepo.deleteById(ClassA.getId()) it will delete ClassA.

This should either be stated in the documentation or fixed in my opinion. It almost caused major issues in our project. @davidkelly