Not understanding Kotlin in combination with Generics.
I was trying to move some of my java towards kotlin. Couple of those classes are spring-data repositories and a generic service that takes as generic parameter a type of repository, e.g.:
@Transactional
interface ForumRepository : CrudRepository<Forum, Long> {
fun findByName(name: String): Forum?
}
Then the GenericKotlinService :
abstract class GenericKotlinService<T>(val repository: CrudRepository<Any, Serializable>) {
fun <T> findOne(id: Serializable): T {
return repository.findOne(id) as T
}
fun delete(id: Any) {
repository.delete(id)
}
}
However, now when I try to create a service that uses this generic service with a specific crudRepository I always get errors, e.g.
class ForumService @Autowired constructor(repository: ForumRepository) : GenericKotlinService<Forum>(repository) {
open fun findByName(name: String) = repository.findByName(name)
}
or
class ForumService : GenericKotlinService<Forum> {
@Autowired
constructor(repository: ForumRepository) : super(repository)
open fun findByName(name: String) = repository.findByName(name)
}
The error is
required CrudRepository<Forum, Long> but got a ForumRepository.
When I use the following java GenericService:
public abstract class GenericService<T> {
private final CrudRepository repository;
public GenericService(CrudRepository repository) {
this.repository = repository;
}
public T findOne(Serializable id) {
return (T) repository.findOne(id);
}
public void delete(Serializable id) {
repository.delete(id);
}
}
and use this one in the ForumService:
class ForumService @Autowired constructor(val repository: ForumRepository) : GenericService<Forum>(repository) {
open fun findByName(name: String) = repository.findByName(name)
}
everything works. I do not see how I can use my GenericKotlinService instead?
The thing is that ForumRepository is not CrudRepository<Any, Serializable>. But it can be convertible to CrudRepository<Any, Serializable> if both type parameters are in out positions. So you can either define the CrudRepository in the following way
interface CrudRepository<out T, out U>
or accept CrudRepository with out type parameters in GenericKotlinService constructor
abstract class GenericKotlinService<T>(
val repository: CrudRepository<out Any, out Serializable>
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With