如何在Java中构建通用实体存储库
我有一个通用存储库类,如下所示:如何在Java中构建通用实体存储库,java,generics,Java,Generics,我有一个通用存储库类,如下所示: public class HibernateRepository<E extends Object, EId> implements EntityRepository<E, EId> { // Many things that are working fine @Override public E getById(EId id) { return entityManager
public class HibernateRepository<E extends Object, EId>
implements EntityRepository<E, EId> {
// Many things that are working fine
@Override
public E getById(EId id) {
return entityManager.getReference(E.class, id); // <<< Error here!
}
}
public class HibernateRepository<E extends Object, EId>
implements EntityRepository<E, EId> {
private Class<E> clazz;
public HibernateRepository(Class<E> clazz) {
this.clazz = clazz;
}
@Override
public E getById(EId id) {
return entityManager.getReference(clazz, id); // <<< Error here!
}
}
请注意,我不想将所需的类传递给方法,因为我已经在类定义中这样做了
此类的用法可以是:
public class MyClassRepositoryHibernate
extends HibernateRepository<MyClass, Long> {
}
公共类MyClassRepositoryHibernate
延长冬眠期{
}
现在,这个新的存储库在MyClass
实例上工作,并且Id
是用Long
键入的
在Java中可能吗?您必须将实际的类类型传递给
HibernateRepository的构造函数,并在整个方法中使用它。JVM不知道运行时“E”是什么,因此需要提供具体的类类型
通过在构造函数中使用泛型参数类型,可以确保不会错误地实例化对象,如下所示:
public class HibernateRepository<E extends Object, EId>
implements EntityRepository<E, EId> {
// Many things that are working fine
@Override
public E getById(EId id) {
return entityManager.getReference(E.class, id); // <<< Error here!
}
}
public class HibernateRepository<E extends Object, EId>
implements EntityRepository<E, EId> {
private Class<E> clazz;
public HibernateRepository(Class<E> clazz) {
this.clazz = clazz;
}
@Override
public E getById(EId id) {
return entityManager.getReference(clazz, id); // <<< Error here!
}
}
公共类HibernateRepository
实施实体报告{
私人课堂;
公共休眠存储(类clazz){
this.clazz=clazz;
}
@凌驾
公共E getById(EId id){
返回entityManager.getReference(clazz,id);//类型将在编译后被擦除,因此不可用。这称为类型擦除。您必须将类对象传递到某个位置。我在类声明中传递它。这还不够吗?从技术上讲,您不需要。这些信息在编译后被擦除,在运行时未知。这就是泛型在j中的实现方式ava.如果您正在子类化HibernateRepository
,并在子类中为E
提供一个具体类型,则该信息可用且可以检索。例如,请参阅Spring的GenericTypeResolver
。