表格:
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 /我该如何处理?
答案 0 :(得分:2)
您有此问题,因为您的方法显式返回了AbstractHistory
而不是子类型。
您可以尝试添加其他类型,但是我担心它会失败:
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();
}
或通过其他界面:
public interface FindFirst<T> {
T findFirst();
}
public interface StudentHistoryRepository extends CrudRepository<StudentHistory, Long>, FindFirst<StudentHistory> {}