Home > database >  Issue while implementing a interface which extends to MongoRepository interface in Kotlin
Issue while implementing a interface which extends to MongoRepository interface in Kotlin

Time:09-05

I am trying to use the in built methods of MongoRepository<T,ID> interface to interact with mongo.

interface MovieRepository : MongoRepository<Movie, String> {

}

But when I try to implement the "MovieRepository" using class. Its asking me to implement all the member functions defined in "MongoRepository" as well

class ControllerClass(private val MovieRepository: MovieRepository): MovieRepository {}

This is what i get when i initialize my controller class:

Class 'ControllerClass' is not abstract and does not implement abstract member public abstract fun <S : Movie!> save(entity: S): S

Is there any way so that i do not need to defined all those MongoRepository's functions again in my ControllerClass?

CodePudding user response:

You don't usually implement a repository interface yourself: you let Spring do it for you!

First, you define your interface, as you have done:

interface MovieRepository : MongoRepository<Movie, String> {
    // Add any abstract methods you'll need here…
}

Then, you autowire a property of that type. In Kotlin, you can either do it in the primary constructor, e.g.:

@Controller
class ControllerClass @Autowired constructor(
    private val movieRepository: MovieRepository
) {
    // …code…
}

Or as a plain property. (In this case, because you can't specify an initial value, you have to make the property a var; it must either be nullable — requiring !! everywhere you use it — or, better, make it lateinit.)

@Controller
class ControllerClass {
     @Autowired private lateinit var movieRepository: MovieRepository

    // …code…
}

Spring will then create some synthetic class implementing that interface, and set your property to it. (You don't need to worry about how it does that — just as you don't need to worry about all the other magic it does, much of which involves creating synthetic subclasses. That's why Spring objects generally need to be made open — and why there's a Spring plugin which takes care of doing that.)

It's more usual to use the repository in a service class, and then call that from your controller class — at least, that pattern tends to scale better, and be easier to follow and to test. But doing so directly should work too. Either way, you can call whichever repository method you need, e.g. movieRepository.findAll().

See the Spring docs; they use Java, but it's mostly trivial to convert to Kotlin.

  • Related