I have the following interface:
public interface UserRepository<T extends User> {
List<T> findAll(UserCriteria userCriteria, PageDetails pageDetails);
T findByEmail(String email);
}
And its implementation:
@Repository
public class JpaUserRepository implements UserRepository<JpaUser> {
public List<JpaUser> findAll(UserCriteria userCriteria, PageDetails pageDetails) {
//implementation
}
public JpaUser findByEmail(String email) {
//implementation
}
}
Now, when I call:
User user = userRepository.findByEmail(email);
in my service class, everything is fine.
But when I call:
List<User> users = userRepository.findAll(userCriteria, pageDetails);
I get unchecked assignment warning with a reason that userRepository has raw type, so result of findAll is erased. If this is indeed the case, shouldn't findByEmail
behave the same? It just doesn't seem very consistent.
How can I eliminate the raw type in this scenario? I've tried few things:
Removing <T extends User>
from interface and applying it to method like this:
<U extends User> List<U> findAll(UserCriteria userCriteria, PageDetails pageDetails);
That works fine for the service, but repository implementation now gives warning about unchecked overriding (return type requires unchecked conversion).
I've also tried removing generics from interface and method, while keeping the return list generic:
List<? extends User> findAll(UserCriteria userCriteria, PageDetails pageDetails);
That solves the problem, no warnings, but requires me to write the service like this:
List<? extends User> users = userRepository.findAll(userCriteria, pageDetails);
And it feels a bit clunky (maybe it's just me, so please, let me know if this is acceptable from "good programming" perspective).
Either way, is it possible to get List<User>
without raw type warnings, while keeping repository untouched?
Thanks a lot for your time.
EDIT: I am not looking for a way to cast the list.
EDIT 2: Repository declaration:
private final UserRepository userRepository;
Some of you suggested to change that declaration to UserRepository<User> userRepository;
and thats successfully removes the warnings but Spring cannot find the bean to autowire this way as JpaUserRepository is UserRepository<JpaUser>
. Service layer does not know about repository implementation.