I want to create a JPA transaction for a JSE app that returns a result.
我想为返回结果的JSE应用程序创建JPA事务。
@SuppressWarnings("unchecked")
public static <T> T transaction(EmWorker worker, Class<T>clazz){
EntityManager em = createEntityManager();
em.getTransaction().begin();
// >>> My Functional interface
Object result = worker.work(em);
em.getTransaction().commit();
em.close();
return (T)result;
}
It works for fetching a single object :
它适用于获取单个对象:
FunkoPop gandalf=EmFactory.transaction( eManager -> {
return eManager.find(FunkoPop.class, 1);
}, FunkoPop.class);
But now, I want a List
of FunkoPop
.
但现在,我想要一个FunkoPop列表。
List<FunkoPop> list =EmFactory.transaction( e -> {
String query = "SELECT f FROM FunkoPop f ";
List<FunkoPop> l = e.createQuery(query, FunkoPop.class).getResultList();
return l;
}, List<FunkoPop>.class); //Won't compile ; or List.class gives warnings
The transaction
needs two arguments : a lambda and a class. I approximatively understand that I cannot capture the type List<FunkoPop>.class
as this parameter will loose the <FunkoPop>
generic. What would be the solution to have no warnings ?
该事务需要两个参数:lambda和class。我近似理解我无法捕获类型List
3 个解决方案
#1
1
you can't because there is no List<FunkoPop>
type. All there is a List
.
你不能,因为没有List
You may however do it the hard way:
但是你可能会这么做:
List<T> transaction(EmWorker worker, Class<T>clazz) {
...
List<T> l = (List<T>)e.createQuery(query, clazz).getResultList();
return l;
}
You might need to rename the method.
您可能需要重命名该方法。
#2
1
Add a second functional interface to produce lists:
添加第二个功能接口以生成列表:
public static interface EmListWorker<T> {
public List<T> work(EntityManager em);
}
public static <T> List<T> transaction(EmListWorker<T> worker, Class<T>clazz){
EntityManager em = createEntityManager();
em.getTransaction().begin();
// >>> alternative Functional interface
List<T> result = worker.work(em);
em.getTransaction().commit();
em.close();
return result;
}
#3
0
Using Function<EntityManager, T>
mentioned by @Holger is great. It's much simpler to implement : no Function Interface and no dirty cast. And it returns a checked type.
使用@Holger提到的函数
Implementation :
public static <T> T transaction(Function<EntityManager,T> worker){
EntityManager em = createEntityManager();
em.getTransaction().begin();
T result = worker.apply(em);
em.getTransaction().commit();
em.close();
return result;
}
Usage :
FunkoPop gandalf = new FunkoPop("Gandalf");
EmFactory.transaction( em -> {
em.persist(gandalf);
return gandalf;
});
List<FunkoPop> list =EmFactory.transaction( em -> {
String query = "SELECT f FROM FunkoPop f ";
return em.createQuery(query, FunkoPop.class).getResultList();
});
#1
1
you can't because there is no List<FunkoPop>
type. All there is a List
.
你不能,因为没有List
You may however do it the hard way:
但是你可能会这么做:
List<T> transaction(EmWorker worker, Class<T>clazz) {
...
List<T> l = (List<T>)e.createQuery(query, clazz).getResultList();
return l;
}
You might need to rename the method.
您可能需要重命名该方法。
#2
1
Add a second functional interface to produce lists:
添加第二个功能接口以生成列表:
public static interface EmListWorker<T> {
public List<T> work(EntityManager em);
}
public static <T> List<T> transaction(EmListWorker<T> worker, Class<T>clazz){
EntityManager em = createEntityManager();
em.getTransaction().begin();
// >>> alternative Functional interface
List<T> result = worker.work(em);
em.getTransaction().commit();
em.close();
return result;
}
#3
0
Using Function<EntityManager, T>
mentioned by @Holger is great. It's much simpler to implement : no Function Interface and no dirty cast. And it returns a checked type.
使用@Holger提到的函数
Implementation :
public static <T> T transaction(Function<EntityManager,T> worker){
EntityManager em = createEntityManager();
em.getTransaction().begin();
T result = worker.apply(em);
em.getTransaction().commit();
em.close();
return result;
}
Usage :
FunkoPop gandalf = new FunkoPop("Gandalf");
EmFactory.transaction( em -> {
em.persist(gandalf);
return gandalf;
});
List<FunkoPop> list =EmFactory.transaction( em -> {
String query = "SELECT f FROM FunkoPop f ";
return em.createQuery(query, FunkoPop.class).getResultList();
});