Reputation: 1442
I have such interface for repository
public interface CrudRepository<T, ID> {
<S extends T> S save(S entity);
Optional<T> findById(ID id);
Class<T> getEntityClass();
}
And I need to implement class which provide aggregated usage of all repositories
public class PersistenceManager {
private final Map<Class<?>, CrudRepository> repositories;
public PersistenceManager(List<CrudRepository> repository) {
repositories = repository.stream()
.collect(Collectors.toMap(
CrudRepository::getEntityClass,
rep -> rep));
}
public void store(EntityWrapper<? extends BaseEntity> entity) {
Optional.of(repositories.get(next.getType()))
.orElseThrow(() -> new IllegalStateException("No repository class for entity" + entity.getType()))
.save(entity.getObject());
}
public <T extends BaseEntity, ID> Optional<T> findById(Class<T> clazz, ID id) {
return Optional.of(repositories.get(clazz))
.orElseThrow(() -> new IllegalStateException("No repository class for entity" + clazz.getSimpleName()))
.findById(id);
}
}
This implementation works but I'm worried that CrudRepository is not parametrised. I've tried something like CrudRepository<? super BaseEntity, ?>
but it works only for store() method.
Is there a way to improve this code with type parametrisation or that's ok as is?
Upvotes: 0
Views: 181
Reputation: 340
In my opinion, this is good enough. Your CrudRepository::getEntityClass can only return the same class as the parameter type of the repository. Since this class is the key in your map, it's not possible to get the wrong class in findById()
Upvotes: 1