我有一个纯粹的JAVA项目,我用maven在eclipse中开发。它具有使用JPA和EclipseLink的持久性功能,可将数据保存到Apache Derby中。该项目在单元测试和独立的Java应用程序中完美地工作,我在其中直接从我的代码中实例化EntityManagerFactory:
public class JPAUtil
{
private static EntityManagerFactory factory = Persistence.createEntityManagerFactory("unit-name");
private static Map<Long, EntityManager> ems = new HashMap<Long, EntityManager>();
private JPAUtil(){}
/**
* Get an entity manager
*/
public static EntityManager em(Long id)
{
EntityManager result = null;
if (ems.containsKey(id))
{
result = ems.get(id);
if(!result.isOpen())
{
result = createEntityManager();
ems.put(id, result);
}
}
else
{
result = createEntityManager();
ems.put(id, result);
}
return result;
}
private static EntityManager createEntityManager()
{
EntityManager result =
// factory.createEntityManager(SynchronizationType.SYNCHRONIZED);
factory.createEntityManager();
return result;
}
}
现在,当我将它添加到GWT项目中时,我遇到了一些非常难以调试/解决问题的问题。
问题1:
如果我使用上面的JPAUtil类来实例化EntityManagers以便在每个RPC请求上使用它。但是,如果GWT客户端开始向服务器端发出多个请求,而后者又试图从JPA层提取数据,则会在读取时发生多个神秘的ConcurrencyException(有或没有延迟加载 - 似乎没有区别)
当我不使用上面的类时,尝试使用以下行将EntityManager“注入”到GWT ServiceImpls(servlets)中,尝试使用NullPointerException访问数据层崩溃:
@PersistenceContext(unitName = "unit-name")
transient protected EntityManager em;
我显然在想,这是从GWT访问持久层的更合适的方法。但是,我在访问EntityManager时得到NullPointerExceptions,因此GWT的开发Jetty服务器不能自己注入EntityManager。我对这类问题的技巧似乎有限,而且我的Google-FU似乎也无能为力。所以要提出一个具体的问题:
如何最好地解决在后端使用JPA创建快速,稳定的GWT应用程序的问题?
提前谢谢你, el.nicko
答案 0 :(得分:0)
您需要同步对HashMap
的访问权限,因为多个线程可以并行处理多个RPC请求。建议您将HashMap
替换为ConcurrentHashMap
或将同步放在em
方法上。
@Inject
可能不起作用,因为GWT servlet不能识别CDI。