I'm buidling a backend that will fetch some data from several externals APIs, to populate DB after some processes, and then expose these data via a rest api. Using JPA and postgresql, in springboot.
I have created the entities, repositories and fetch external apis from a webclient.
However, I have a dependency injection issue. I read tons of articles and issues, but can not make it work. When trying to inject the repository, I got the well known error lateinit var not initialized
.
I also tried constructor injection, but still doesn't work. It seems that the repository is not considered to be a bean that could be autowired.
Any help would be appreciated
FIXED SEE SOLUTION BELOW. PB WAS IN THE SERVICE
Application. Running the startuprocess from the context
@SpringBootApplication(exclude = [JacksonAutoConfiguration::class])
class SpringbootkotlinApplication
fun main(args: Array<String>) {
val context = runApplication<SpringbootkotlinApplication>(*args)
val startupProcess = context.getBean(StartupProcesses::class.java)
startupProcess.fetchGroup()
}
startup class as @component :fetches external api and calls a service to save data in db
@Component
class StartupProcesses {
fun fetchGroup() {
val fetch = IronMaidenSourceApi.fetchIronMaidenSource() //<-- fetch ext api OK
SplitDataSourceToEntities().populateGroup(fetch) //<-- call service to populate db
}
}
Service that should populates the DB through repository but error in lateinit repo
@Service
class SplitDataSourceToEntities {
@Autowired
lateinit var repo:IronMaidenGroupRepository // <-- error is here
fun populateGroup(dto: DTOIronMaidenAPi): IronMaidenGroupEntity {
val dbgroup = IronMaidenGroupEntity(
groupId = dto.id!!,
name = dto.name ?: ""
)
return repo.save(dbgroup)
}
}
the repo, extending JPA repository
import com.jerome.springbootkotlin.model.dbentities.ironmaidengroupentity.IronMaidenGroupEntity
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface IronMaidenGroupRepository:JpaRepository<IronMaidenGroupEntity, String> {
}
SOLUTION
Service should be defined like this (the SplitDataSourceToEntitiesclass should also be late init
instead of beeing instantiated)
@Component
class StartupProcesses {
@Autowired
lateinit var splitDataSourceToEntities: SplitDataSourceToEntities // <--add this lateinit
fun fetchGroup() {
val fetch = IronMaidenSourceApi.fetchIronMaidenSource()
splitDataSourceToEntities.populateGroup(fetch) //<-- fix is here
}
}