我正在使用 Glassfish v3 服务器。
通常与 EJB3 + JPA (Eclipselink) 的数据库连接是通过注入完成的,使用 @PersistenceUnit 或 @Persistencecontext。
但是,我的 App 中有 3 层:
核心(包含业务逻辑、实体、异常处理等)
在它之上的 EJB,调用正确的核心对象和方法来完成这项工作。这个 EJB 被我们 ERP 的其他内部模块调用。
其之上的 REST 层供前端网站使用。
我不想在 EJB 中获得 entityManager,也不想获得 EMF(EM 工厂),因为我希望我的中间层不知道它下面使用了一个 DB。毕竟,我以后可以决定将我的核心实现更改为不使用 DB 的实现。
我只看到两个不好的解决方案:
1)每次调用需要DB连接的核心层方法时添加一个EM参数。非常丑陋,与我上面所说的背道而驰。
2)在需要数据库连接的每个核心方法中,我创建了一个工厂、一个 EM,使用它们,然后将它们都关闭。
我试图在中间切开一些东西,每个核心级别的类都有一个工厂,并且在每种方法中都创建和关闭了 EM。但我仍然有这样的内存泄漏:
javax.servlet.ServletException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: In-use connections equal max-pool-size and expired max-wait-time. Cannot allocate more connections.
我想这是因为如果我的 EJB 方法之一使用 10 个不同的对象,它会创建 10 个 EM 工厂,并且没有一个是关闭的。
Core 对象中的典型用法示例:
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// do some stuff with em; for example persist, etc
em.flush();
em.close();
我应该去解决方案2吗?有没有办法在这个核心级别使用单个 EM 工厂?我似乎 JPA 规范假设您将仅在 EJB 级别使用实体,这在多层应用程序中是不好的。
编辑:这是尝试 @Inject 后的当前状态:
在我的 CORE jar 的 /META-INF 目录中添加了一个空 beans.xml 文件。
父 DAO 类现在是这样的:
公共类 ExampleBZL {
public EntityManagerFactory emf; @Inject public Emf emfobject; public ExampleBZL() { this.emf = emfobject.emf; }
Emf 类非常简单,而且是无状态的。
@Stateless 公共类 Emf 实现 EmfAbstract {
@PersistenceUnit(unitName = Setup.persistenceUnitName) public EntityManagerFactory emf; public Emf() { }
}
我一定是做错了什么,但注入不起作用,尽管在 glassfish 中我在引擎列表中看到“[ejb,weld,web]”,因此加载了 CDI。
Servlet.service() for servlet Jersey Web Application threw exception
java.lang.NullPointerException
at com.blablabla.core.bizlogic.ExampleBZL.<init>(ExampleBZL.java:40)
我是否缺少其他注释?用这两个小注释(一侧是无状态,另一侧是注入)在 JAR 中进行注入真的有效吗?