我希望从那些成功地将JPA与遗留类型产品集成的人那里获得一些反馈。最近,我们的软件团队一直在考虑将JPA功能添加到我们的J2EE软件堆栈中。JPA的强大和灵活性给我们留下了深刻的印象,但我们很难将其与当前的体系结构“干净”地集成在一起。我们在网上找到的大多数JPA示例都太简单,无法应用到我们当前的体系结构中。
我们目前的架构是深度嵌套的。从面向用户的“托管”bean到数据库层,通常有7-8层(有时要深得多)。我们的问题是@PersistenceContext只能在ManagedBeans上使用。我们不希望将所有这些数据访问器类都设为MangedBeans,因为这将导致数十个bean。更不用说你必须对这7-8层中的每一层都进行注入,使它们都成为bean。这简直是一发不可收拾。
我们尝试过的一个想法可能是一个糟糕的想法,那就是让一个单例来跟踪注入的EntityManager,然后在任何层访问它。然而,在重新部署应用程序时,我们已经看到了这方面的问题(我假设是由于过时的类)。
如果能从过去做过类似事情的人那里得到反馈,那就太好了。在开发的这个阶段重新架构是不可能的。有没有一个很好的方法来做到这一点,或者我们正在尝试在一个圆孔中安装一个方形的钉子?
提前谢谢你,
Weblogic 12.1.2
JPA2.0 - EclipesLink
发布于 2014-03-22 14:08:24
我做了一些类似于您提出的“单例”方法的事情(尽管没有使用依赖注入或容器管理的单例)。我所做的大致是:
public static EntityManager getEntityManager(HttpServletRequest request) {
//first, check for a cached instance
EntityManager cachedEm = (EntityManager)request.getAttribute(Constants.ENTITY_MANAGER_REQUEST_KEY);
if (cachedEm != null) {
if (! cachedEm.isOpen()) {
//somebody has closed the cached EntityManager; discard it and get a new one
request.removeAttribute(Constants.ENTITY_MANAGER_REQUEST_KEY);
return getEntityManager(request);
}
return cachedEm;
}
//no cached instance, get a fresh one from the factory and cache it for this request
cachedEm = factory.createEntityManager();
request.setAttribute(Constants.ENTITY_MANAGER_REQUEST_KEY, cachedEm);
return cachedEm;
}所以我有一个静态可访问的实用函数,它可以用来获取一个针对当前请求的EntityManager。这确保了在正常情况下,针对给定的HTTP请求所做的所有处理都将使用单个EntityManager (对于极少数情况下这样做是有用和适当的,还有一些额外的方法可用于创建特别/独立的EntityManager实例)。包含这个工具函数的类不是容器管理的;它只是一个普通的静态工具类。
我还对其进行了连接,以便在呈现/编写响应之后,监督该过程的Spring控制器自动关闭请求的EntityManager,这意味着在代码中只有一个点需要担心在EntityManager上调用close()。因此,它相当接近容器管理的持久性,而不需要定制的容器管理。
我真的不能评论这种方法在热(重新)部署中的表现如何(我很少在实践中进行热部署,因为我注意到它们往往会消耗PermGen空间,即使其他一切都像应该的那样工作),尽管我还没有看到它有任何具体的问题。我也看不到为什么会有这样的原因。
如果您的容器/web框架试图不惜一切代价对您隐藏HttpServletRequest,那么这种方法可能有点笨拙(或者您将不得不修改它以使用您的框架提供的任何请求代理)。如果使用mock-objects进行大量测试,显然静态实用程序类会使测试变得更加困难。但实际上,上面的代码在几个不同的应用程序中都很好地服务于我。
https://stackoverflow.com/questions/22573912
复制相似问题