Search code examples
spring-bootkotlinspring-data-jpakoin

Inject Spring Jpa Repositories and Spring Services with Koin


I want to use koin as my main dependency injection library inside a spring boot 3 project, but i don't know how to initialize an instance of a Jpa repository from its interface.

say i have this

interface AccountRepository : JpaRepository<Account, UUID> {
  fun findAccountByEmail(email: String): Account?
  fun findAccountByPhoneNumber(phoneNumber: String): Account?
}

i want to add it to a singleton like

val repositories = module {
single <AccountRepository> { /* I Don't know what to put here */ }
}

so i can later inject it like

var accountRepo: AccountRepository by inject()

how should i go about doing that?


Solution

  • Found a solution by passing the EntityManager to the module responsible for creating the repositories from the SpringBoot application like so:

    @SpringBootApplication
    class Application
    
    fun main(args: Array<String>) {
      val context = runApplication<Application>(*args)
      startKoin {
        modules(
          GenericModules,
          RepositoriesModule(context.getBean(EntityManager::class.java))
        )
      }
    }
    

    I was able to do this

    val RepositoriesModule: (EntityManager) -> Module = { entityManager ->
      module {
        factory<AccountRepository> {
          JpaRepositoryFactory(entityManager).getRepository(AccountRepository::class.java)
        }
    
        factory<SessionRepository> {
          JpaRepositoryFactory(entityManager).getRepository(SessionRepository::class.java)
        }
      }
    }
    

    then later injected them like:

    val accountRepository: AccountRepository by inject(AccountRepository::class.java)
    
    Note: Don't forget to add @Transactional on class level of whatever class is working with these repositories to allow for transactional operations