下午好,这是我在StackOverflow上的第一个问题。
我不是Spring框架的专家,有时我会因为相对容易解决的问题而迷失了很多时间,但是这次我无法真正摆脱它。
我正在尝试在自定义的Spring Data Repository中实现一个方法,该方法应该与多个Entity一起工作,并根据Entity字段上特定注释的存在对数据库执行一些操作。
我已经尝试了很多在Internet上找到的变通办法,但是我实际上无法实现所需的结果。我会尝试更具体:
这是带有注释的示例实体:
@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
}
}
这实际上是与用户实体一起使用的,但是我需要找到一种方法,使其对扩展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;
}
并使用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回答之后,我尝试使用Spring提供的GenericTypeResolver,但实际上我没有使用null。 documentation指出,如果返回null,则表示它无法解析类型。
这是我使用的代码:
private final Class<?>[] genericType;
public MyCustomRepositoryImpl(){
this.genericType = GenericTypeResolver.resolveTypeArguments(getClass(), MyCustomRepositoryImpl.class);
}
我认为某种程度上,这个“问题”与Spring在幕后所做的所有代理有关,但是我目前没有确切的主意。
如果有人有任何线索,请在此处写下,我们将不胜感激。
答案 0 :(得分:0)
我遇到了类似的问题,这个answer帮助了我。之所以得到NoSuchBeanDefinitionException,是因为您试图注入一个类类型字段,但没有在Spring上下文中创建一个。您需要做的是使用Spring的GenericTypeResolver查找泛型并相应地处理数据。 希望这会有所帮助
答案 1 :(得分:0)
实际上,我参考了answer指向的@amineT,创建了一个示例项目,看它是否适合您的问题。
根据我的理解,您想要的是确定运行时Bean的类型,而不是CustomRepositoryImpl的类型。构建示例项目后,我发现您的代码几乎正确。
以下是我对您的代码进行处理以使其正常工作的示例:
@Override
public void myCustomMethod(Class cls, Object id){
Object user = entityManager.find(cls,id);
List<Field> markedFields = MyAnnotationProcessor.getAnnotated(cls);
//Here I'll manipulate the fields that i've obtained
...
entityManager.persist(u);
//And then i'm persisting the modified entity
}
此外,这是我创建的示例项目的github。