GWT和JPA并发,@ PersistenceContext,NullPointerException

时间:2015-01-10 19:32:16

标签: java jpa gwt eclipselink

我有一个纯粹的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

1 个答案:

答案 0 :(得分:0)

您需要同步对HashMap的访问权限,因为多个线程可以并行处理多个RPC请求。建议您将HashMap替换为ConcurrentHashMap或将同步放在em方法上。

@Inject可能不起作用,因为GWT servlet不能识别CDI。