java - 与 Spring Data JPA 和泛型类型混淆

标签 java spring generics spring-data-jpa

表格:

StudentHistory 1--->n Student
TeacherHistory 1--->n Teacher

我尝试重新组合历史的 JPA 行为,因为它们做同样的事情(例如,从给定的历史中检索学生/老师)。

具有泛型类型的实体:

// Entities
public abstract class AbstractHistory <T> {}
public class StudentHistory extends AbstractHistory<Student> {}
public class TeacherHistory extends AbstractHistory<Teacher> {}

具有通用类型的存储库:

// repositories
public interface IHistoryRepository<T> extends CrudRepository<AbstractHistory<T>, Long> {
    public AbstractHistory<T> findFirst();
}    
public interface StudentHistoryRepository extends IHistoryRepository<Student> {}
public interface TeacherHistoryRepository extends IHistoryRepository<Teacher> {}

我认为我可以做到:

StudentHistory stuHisto = new StudentHistoryRepository().findFirst(); 

但我收到此错误:

    // err ->  Type mismatch: cannot convert from AbstractHistory<Student> to StudentHistory

1/为什么我无法从“StudentHistoryRepository”中检索“StudentHistory”?

2/我应该如何处理这个问题?

最佳答案

您遇到此问题是因为您的方法显式返回 AbstractHistory 而不是子类型。

  1. 您需要转换...
  2. ...如果您的存储库实现能够理解每个 T,您都会获得特定的历史记录。

您可以尝试添加其他类型,但我担心它会失败:

public interface IHistoryRepository<
  T,
  H extends AbstractHistory<T>
> extends CrudRepository<H, Long> {
    public H findFirst();
}    
public interface StudentHistoryRepository extends IHistoryRepository<Student, StudentHistory> {}
public interface TeacherHistoryRepository extends IHistoryRepository<Teacher, TeacherHistory> {}

我不知道你用的是什么框架,从名字上看可能是Spring Data;虽然我过去用过它,但我不知道它是否能够做到这一点。

毕竟,它需要获取具体类,并且由于它是泛型,类型删除可能会干扰(如果有关表示 H 的具体类型的信息在反射中丢失,那么 Spring Data 在这里可能无法做太多事情,除非你通过注释或其他东西来帮助它)。

另一个可行的解决方案是针对每个子界面执行此操作:

public interface StudentHistoryRepository extends CrudRepository<StudentHistory, Long> {
  StudentHistory findFirst();
}

或者使用另一个接口(interface):

  public interface FindFirst<T> {
    T findFirst();
  }

  public interface StudentHistoryRepository extends CrudRepository<StudentHistory, Long>, FindFirst<StudentHistory> {}

关于java - 与 Spring Data JPA 和泛型类型混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52635891/

相关文章:

java - 处理多个异步操作并处理每个异步操作以进行进一步处理的最佳方法是什么?

java - 使用 ApplicationContext 在运行时以编程方式修改 spring bean

c# - 转换为动态类型变量的通用列表

delphi - 在 Delphi 中将 TObjectList 祖先转换为通用集合

java - 无法分配给没有类型参数的 Function

java - 将 Java LinkedHashMap 转换为 C++ std::map

javascript - Vert.x:从 Java 部署 JavaScript Verticle 失败

java - 静态方法可以在 Java 中调用自身吗?

spring - 在 Controller 内部构造时, Autowiring 服务以命令 Grails 中的对象的正确方法

java - 类路径资源 [spring/config/BeanLocations.xml] 无法打开,因为它不存在