Обобщения c CrudRepository
Есть 4 подобных репозитория(в пример один из них):
public interface ClassRoomRepository<T> extends CrudRepository<T,Long> {
List<T> findByName(String name);
}
Есть контроллер в котором я его использую:
@Autowired
private ClassRoomRepository<ClassRoom> classRoomRepository;
Программа не отрабатывает Spring выдает ошибку, хотя если в CrudRepository записать <ClassRoom,Long> то все отрабатывает, в документации прочитал, что он принимает T. Почему я не могу воспользоваться дженериками в данном случае, ведь все равно произойдет стирание до Object?
Ответы (1 шт):
Причина в том, что при определении переменной информация о типе стирается, а при наследовании от обобщенного класса/интерфейса с четко заданными параметрами - нет.
Т.е. вот этой записи
private ClassRoomRepository<ClassRoom> classRoomRepository;
тип ClassRoom существует только на этапе компиляции, а самом байткоде остается только приведение типа.
Важно, что в runtime spring никак не может узнать, что за тип был передан в качестве аргумента обобщенному интерфейсу ClassRoomRepository. А spring-и нужно знать этот тип, для того чтобы знать с какой сущностью идет работа, в какую таблицу БД делать запросы, какого типа сущности создавать и т.д.
Если же у вас ClassRoomRepository не обобщенный тип, и при наследовании от CrudRepository явно задан тип сущности, то эта информация о параметре сохраняется в runtime и доступна через рефлексию. И таким образом spring может ее достать.
Почитайте больше подробностей о том как это работает в этом ответе и в этом ответе