Reputation: 539
I am no expert with generics and as I am trying to do a reengineering of some classes to avoid code repetition, I am forcing myself to use generics in order to do it the best way possible.
I am getting the next error in the lines I marked:
The method delete(Long) in the type CrudRepository is not applicable for the arguments (capture#5-of ? extends KeyProfileEntity)
Here my class:
public abstract class KeyProfileService {
protected CrudRepository<? extends KeyProfileEntity, Long> myRepository;
public List<KeyProfileEntity> getList() {
List<KeyProfileEntity> result = new ArrayList<>();
this.myRepository.findAll().forEach(result::add);
return result;
}
public KeyProfileEntity create(KeyProfileEntity entity) {
return this.myRepository.save(entity); //error
}
public boolean delete(long id) {
if (this.myRepository.exists(id)) {
this.myRepository.delete(this.myRepository.findOne(id));//error
return true;
}
return false;
}
public void update(KeyProfileEntity entity) {
this.myRepository.save(entity); //error
}
public KeyProfileEntity getEmployee(long id) throws NotFoundEntryException {
if (this.myRepository.exists(id))
return this.myRepository.findOne(id);
throw new NotFoundEntryException();
}
}
I think this is all the info you guys need, otherwise comment and I will attach more.
Thanks in advance!
Upvotes: 0
Views: 1261
Reputation: 7166
You can fix it by removing the <? extends ...>
bound wildcard from myRepository
:
protected CrudRepository<KeyProfileEntity, Long> myRepository;
As far as I can see, your class will be still usable, even with subclasses of KeyProfileEntity
:
KeyProfileService service = new KeyProfileServiceImpl();
service.update(new ChildKeyProfileEntity());
There will be only one limitation: getList()
will always return a List<KeyProfileEntity>
, not a List<ChildKeyProfileEntity>
.
Alternatively, you can make the KeyProfileService
generic and make sure you use a bound, known subtype:
public abstract class KeyProfileService<K extends KeyProfileEntity> {
protected CrudRepository<K, Long> myRepository;
public List<K> getList() { // using K
List<K> result = new ArrayList<>(); // here too
this.myRepository.findAll().forEach(result::add);
return result;
}
public K create(K entity) { // using K
return this.myRepository.save(entity);
}
...
}
Upvotes: 2