Java 使用泛型和jpa EntityManager方法

Java 使用泛型和jpa EntityManager方法,java,hibernate,generics,jpa,Java,Hibernate,Generics,Jpa,我可以同时使用泛型和JPA吗 我试图将四个类的对象持久化到我的数据库中。这是我的PersistService类: public class PersistService<T> { private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("fileUploadProject"); public static EntityManager getEntityManager() {

我可以同时使用泛型和JPA吗

我试图将四个类的对象持久化到我的数据库中。这是我的PersistService类:

public class PersistService<T> {
private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("fileUploadProject");

public static EntityManager getEntityManager() {
    return emf.createEntityManager();
}

// Write Client to Database
public static <T> void persist(T obj) {
    EntityManager em = getEntityManager();
    EntityTransaction et = em.getTransaction();
    et.begin();
    em.persist(obj);
    et.commit();
    em.close();
}
}
公共类持久化服务{
私有静态EntityManagerFactory emf=Persistence.createEntityManagerFactory(“fileUploadProject”);
公共静态EntityManager getEntityManager(){
返回emf.createEntityManager();
}
//将客户端写入数据库
公共静态无效持久(T obj){
EntityManager em=getEntityManager();
EntityTransaction et=em.getTransaction();
等开始();
em.persist(obj);
et.commit();
em.close();
}
}
但后来我在移除对象时遇到了问题。除上述方法外,PersistService类中还有以下方法:

// Remove an object from the Database if they exist
public static <T> void remove(Long id) {
    EntityManager em = getEntityManager();
    EntityTransaction et = em.getTransaction();
    <T> obj = em.find(<T>.class, id);
}
//从数据库中删除对象(如果存在)
公共静态无效删除(长id){
EntityManager em=getEntityManager();
EntityTransaction et=em.getTransaction();
obj=em.find(.class,id);
}

最后一行给了我一个编译时错误。我也尝试过
.class
T
class
T.class
,但它仍然会给我一个编译时错误。只是学习类型擦除,这个错误是因为这个吗?我如何解决这个问题

您已经开始使用良好的模式。下一步是为每个实体类型创建PersistService的子类。我还将提到,从长远来看,您可能希望每个实体都有一个公共基类或接口。例如,我将其称为
实体
。这个基类(如果是类而不是接口)可以是抽象的,并且可以为所有实体定义通用方法

public interface Entity {
    long getId();
}
您可以在
持久化服务
的实现中使用
实体
定义的方法(当您在此基本服务或代码中的其他地方添加更通用的实体相关业务逻辑时,您会发现这些方法很方便)

您的实体
A
看起来像

public class A extends Entity {
}
您的
持久化服务
将变为

public abstract class PersistService<T extends Entity> {
    // Your common methods (persist, remove, etc.).
    public abstract Class<T> getEntityClass();
}
公共抽象类持久化服务{
//您的常用方法(持久化、删除等)。
公共抽象类getEntityClass();
}
您的特定于实体的服务如下所示

public class APersistService extends PersistService<A> {
    public Class<A> getEntityClass() {
        return A.class;
    }
}
公共类服务扩展了持久性服务{
公共类getEntityClass(){
返回A.class;
}
}
然后在实现
PersistService.remove()
时使用
getEntityClass()
方法


虽然实体特定的子类解决了在类型擦除时获取特定类对象的问题,但您会发现最终希望子类也支持实体特定的查询。

我可能有您正在搜索的答案,在编译时使用泛型类型并不是那么容易。因为java不允许您直接这样做

我自己也有一个黑客,你能试试这样的吗

确保处理您的异常

静态类getGenericType(T){
返回getType(t);
}
静态类getType(对象o){
返回o.getClass();
}

您应该尝试创建一个GenericDao并使子类扩展它您永远不希望在
PersistService
方法中管理事务。您希望基于业务逻辑的逻辑块来管理事务边界。通常,您会执行多个或多个数据库操作,这些操作要么全部成功,要么全部失败,否则您的系统将处于不一致的状态,很难编写代码,也很难从中恢复。您无法在编译时获取类类型。您将花费足够的时间和资源来搜索它。我尝试过做完全相同的事情,但在我的场景中,我使用的抽象类正在实现一个通用接口。我在实现“条目特定服务”时遇到的错误是“无法从类型变量中选择”。
static <T> Class getGenericType(T t){
    return getType(t);
}
static Class<?> getType(Object o){
    return o.getClass();
}