Name Every Method You Actually Use, Even the Free Ones
Why declaring a repository method that the framework would already provide for free is worth the extra line, for the sake of the migration and the optimization pass that come later.
TicketRepository gets a save method declared on it explicitly, even though extending the base repository interface would already make that exact method available without writing a single extra line.
Declaring a Free Method Isn't Redundant, It's a Record
Leaving TicketRepository completely empty would still let TicketRepository.save(...) compile and run, inherited straight from the base interface. Declaring it anyway turns an invisible inherited capability into a visible, intentional one — a record of exactly which operations this repository actually relies on, sitting in plain sight for anyone who opens the file.
Why That Record Matters Later
That record earns its keep the moment anything about the underlying setup changes. Moving to a different database, a different ORM, or hand-writing queries instead of relying on one all require knowing exactly which operations were ever actually being used. Whoever takes on a migration like that has to reimplement each one from scratch, and a repository interface that never named its methods leaves them guessing at a surface they can't see, entirely dependent on an inherited base type that will no longer even exist.
The same visibility pays off without any migration ever happening at all. Someone auditing the codebase for a database performance pass can read straight through every repository, method by method, and see exactly which lookups exist and which of them might actually benefit from an index, instead of hunting across the whole codebase for every implicit call an ORM's inherited interface happened to make available.
Keep reading