使用泛型和jpa EntityManager方法

时间:2016-11-16 15:17:25

标签: java hibernate generics jpa

我可以一起使用泛型和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();
}
}

但是我遇到了删除对象的问题。除了上面的内容之外,我在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);
}

最后一行给出了编译时错误。我也尝试了<T>.class T Class<T>T.class,但它仍然给我一个编译时错误。刚学习Type Erasure,这个错误是因为这个吗?我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

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

public interface Entity {
    long getId();
}

您可以在Entity的实现中使用PersistService定义的方法(当您在此基本服务或代码中的其他位置添加更多通用实体相关业务逻辑时,您可能会发现这些方法很方便)

您的实体A看起来像

public class A extends Entity {
}

您的PersistService变为

public abstract class PersistService<T extends Entity> {
    // Your common methods (persist, remove, etc.).
    public abstract Class<T> getEntityClass();
}

您的特定于实体的服务如下所示

public class APersistService extends PersistService<A> {
    public Class<A> getEntityClass() {
        return A.class;
    }
}

然后在实施getEntityClass()时使用PersistService.remove()方法。

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

答案 1 :(得分:0)

我可能有你正在寻找的答案,好吧,在编译期间使用泛型类型并不容易。因为java不允许你直接这样做。

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

  

请务必处理您的例外情况。

    
static <T> Class getGenericType(T t){
    return getType(t);
}
static Class<?> getType(Object o){
    return o.getClass();
}