Добрый день, это мой первый вопрос здесь, на StackOverflow.
Я не являюсь экспертом в среде Spring, и иногда я теряюсь на много времени из-за проблем, которые относительно легко решить, но на этот раз я действительно не могу выбраться из этого.
Я пытаюсь реализовать метод внутри собственного Spring Data Repository, который должен работать с несколькими сущностями и выполнять некоторые операции с базой данных, основываясь на наличии определенных аннотаций в полях сущности.
Я пробовал много обходных путей, найденных в Интернете, но на самом деле я не в состоянии достичь нужного мне результата. Я постараюсь быть более конкретным:
Это пример сущности с аннотациями:
@Data
@Entity
@MyAnnotation
public class User{
@Id
@MyDataAnnotation
private Long id;
@MyDataAnnotation
private String firstName;
@MyDataAnnotation
private String lastName;
private String userName;
private int followers;
private int following;
}
У меня внутри класса UserService что-то вроде этого:
@Service
public class UserService {
private final UserRepository repository;
public void doSomethingOnUser(Long id){
repository.myCustomMethod(id);
}
}
Для UserRepository я сделал что-то вроде этого, просто очень простые вещи:
@Repository
public interface UserRepository extends CrudRepository<User,Long>,MyCustomRepository<User,Long> {}
У меня есть пользовательский интерфейс репо:
public interface MyCustomRepository<T,ID>{
public void myCustomMethod(ID id);
}
И, наконец, реализация myCustomMethod:
public class MyCustomRepositoryImpl <T,ID> implements MyCustomRepository{
@PersistenceContext
EntityManager entityManager;
@Override
public void myCustomMethod(Object id){
User user = entityManager.find(User.class,id);
List<Field> markedFields = MyAnnotationProcessor.getAnnotated(user.getClass());
//Here I'll manipulate the fields that i've obtained
...
entityManager.persist(u);
//And then i'm persisting the modified entity
}
}
На самом деле это работает с User Entity, но мне нужно найти способ, чтобы он работал для каждого типа домена, управляемого репозиторием, расширяющим MyCustomRepository.
Например, если у меня есть:
public interface WhateverRepository extends CrudRepository<WhateverClass,Long>,MyCustomRepository<WhatheverClass,Long>
myCustomMethod все равно должен делать свои вещи.
Я пытался получить экземпляр Class<T>
с помощью этого фрагмента кода:
private final Class<T> type;
public MyCustomRepositoryImpl(Class<T> type) {
this.type = type;
}
И использование типа вместо User.class, но не удается загрузить ApplicationContext:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.Class<?>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}`
Спасибо, если вы читали до сих пор, надеюсь, что вы можете дать мне несколько советов, и если я не был достаточно ясен, пожалуйста, не стесняйтесь спрашивать меня для получения дополнительной информации.
Обновление:
После ответа @amineT я попытался использовать GenericTypeResolver, предоставленный Spring, но вместо типов я фактически получаю нулевое значение.
Документация гласит, что если возвращается значение null, это означает, что он не смог разрешить тип.
Это код, который я использовал:
private final Class<?>[] genericType;
public MyCustomRepositoryImpl(){
this.genericType = GenericTypeResolver.resolveTypeArguments(getClass(), MyCustomRepositoryImpl.class);
}
Я думаю, что каким-то образом эта "проблема" связана со всеми прокси-серверами, которые Spring делает под капотом, но у меня пока нет точного представления.
Если у кого-то есть какие-либо подсказки, пожалуйста, запишите это здесь, это будет оценено.