Home > database >  Spring mongodb: How to make repositories work with the inheritance structure?
Spring mongodb: How to make repositories work with the inheritance structure?

Time:07-07

I have a collection that stores different documents representing instances of classes inheriting from the same abstract parent class. For each class I have a mongorepository defined as MongoRepository<Volvo, String> that was supposed to query all objects in the collecitons that belong to _class com.repo.Volvo.

However, it seems that the repository queries all documents, not only Volvos, and casts them to instances of Volvo.

How can I make it work with the _class definition, other than adding a filter by _class? Thanks!

CodePudding user response:

One easy solution is to have a collection for each derived class. Annotating each model with that concrete collection make sure that spring only fetches the concrete car model.

Consider the following example:

abstract class Car(
    @field:Id
    var id: String? = null,
    var model: String,
    var wheels: Int,
)

And two concrete models:

@Document(collection = "volvo")
class Volvo(
    id: String? = null,
    model: String,
    wheels: Int
) : Car(id, model, wheels)
@Document(collection = "vw")
class Vw(
    id: String? = null,
    model: String,
    wheels: Int
) : Car(id, model, wheels)

By defining a repository for each manufacturer quering each will be easy

interface VolvoRepository : MongoRepository<Volvo, String>
interface VwRepository : MongoRepository<Vw, String>

Now consider the following basic application wich adds some data into the database and reads then via injected reporitories:

fun main(args: Array<String>) {
    SpringApplication.run(Application::class.java, *args)
}

@SpringBootApplication
@EnableMongoRepositories
open class Application {
    @Bean
    open fun init(volvoRepository: VolvoRepository, vwRepository: VwRepository): CommandLineRunner = CommandLineRunner {
        volvoRepository.save(Volvo(model = "XC90", wheels = 4))
        vwRepository.save(Vw(model = "Golf", wheels = 4))

        println(volvoRepository.findAll().map { it::class.simpleName   " - "   it.id   " - "   it.model })
        println(vwRepository.findAll().map { it::class.simpleName   " - "   it.id   " - "   it.model })
    }
}

Result of those println calls are:

[Volvo - 62c5fb0798ab2c534dccaab0 - XC90]
[Vw - 62c5fb0898ab2c534dccaab1 - Golf]

Hope that this helps. If you would like to have this example code as working reporitory let me know.

  • Related