Thanks for your thoughts. That’s definitely another approach which would work well.
I wouldn’t either one is always better than the other, but it’s certainly less code.
To one of your points I’d like to mention that I’d suggest that no code depends directly on DoctrineProductRepository directly for exactly the reason you mention. Depend on the ProductRepository interface and that code is protected against those sorts of underlying changes. (We’ve named our interfaces slightly differently, in that I’ve removed the *Interface suffix, but the principle is the same).
With your suggestion it’s also worth mentioning that the methods doctrine provides _do_ still form part of the contract that class provides to other objects. You could still call find, findBy, persist, flush, etc even if the IDE would not suggest them due to type-hinting the interface, not the class.
I’d say it feels like a trade-off between more code and less chance of misuse versus less code and more chance of misuse, but your version is certainly an option I’d consider too.