我正在寻找一种从实现 Spring Data JPA Repository
接口(interface)的实例中获取实体类型或类名的方法。
我有许多接口(interface)扩展了一个扩展 Repository
接口(interface)并定义了一些基本查询的基本接口(interface)。
@NoRepositoryBean
public interface EnumerationRepository<T extends IDatabaseEnumeration> extends Repository<T, String> {
// ...
}
public interface SampleEnumerationRepository extends EnumerationRepository<SampleEnumeration> {
}
Spring 允许我将所有这些接口(interface)的实现作为一个集合注入(inject)到一个 bean 中
@Autowired
private Collection<EnumerationRepository<? extends IDatabaseEnumeration>> repositories;
我想将所有这些实现放入 Map
中,以便在通用方法中轻松访问。我想使用实体类型或名称作为键,但我不确定从哪里获得它。有没有办法获得这些属性之一?最好是类类型。
我能够通过这样的查询实现所需的行为。但我想尽可能避免这种解决方案,因为它会产生对底层数据库的依赖。
@Query(value = "select '#{#entityName}' from dual", nativeQuery = true)
public String getEntityName();
最佳答案
@jens-schauder 的回答在我的案例中不起作用,但它为我指明了正确的方向。
Spring 向我注入(inject)了扩展 spring Repository
接口(interface)的接口(interface)实现。因此我必须获取所有接口(interface),过滤掉 spring 内部的接口(interface),所以我最终得到了我定义的接口(interface)。然而,这个接口(interface)还不是通用的,所以我必须得到具有通用类型的它的 super 接口(interface)。
我真的不关心性能,因为这个方法只在 Spring 容器初始化期间调用。
幸运的是,多态性在这种情况下效果很好。所以我只需要在 super 接口(interface)上实现默认方法。像这样
@NoRepositoryBean
public interface EnumerationRepository<T extends IDatabaseEnumeration> extends Repository<T, String> {
// ...
default Class<T> getEntityClass() {
Type[] interfaces = getClass().getInterfaces();
for (Type t : interfaces) {
if (t instanceof Class<?>) {
Class<?> clazz = (Class<?>) t;
if (clazz.getPackage().getName().startsWith(ApplicationConst.BASE_PACKAGE)) {
// Repositories should implement only ONE interface from application packages
Type genericInterface = clazz.getGenericInterfaces()[0];
return (Class<T>) ((ParameterizedType) genericInterface).getActualTypeArguments()[0];
}
}
}
return null;
}
}
我希望这对面临类似问题的其他用户有用。
关于java - Spring Data - 从存储库获取实体名称/类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47759559/