【发布时间】:2015-07-27 03:46:24
【问题描述】:
我正在构建一个基于 Gradle 的 Java SE 应用程序,该应用程序基于 Hibernate 作为我选择的 ORM。我的计划是使用weld-se 以便能够使用CDI 注释在整个应用程序中注入EntityManagers。
基于 Hibernate 文档中常见的 HibernateUtil 帮助类,我转向 JPA 接口并添加了 @Produces 注释以提供生产者方法(我也添加了一个空的 META-INF/beans.xml):
package dao;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class HibernateUtil {
private static final EntityManagerFactory emf = buildEntityManagerFactory();
private static EntityManagerFactory buildEntityManagerFactory() {
try {
return Persistence.createEntityManagerFactory("persistenceUnit");
} catch (Throwable ex) {
System.err.println("Initial EntityManagerFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
@Produces
public static EntityManager createEntityManager() {
return emf.createEntityManager();
}
public static void closeEntityManager(@Disposes EntityManager em) {
System.out.println("Closing EM");
try {
em.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
但是,当我尝试在字段上使用 @Inject 注释时,Weld 无法解析正确的生产者方法并产生异常:
线程“main”中的异常 org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308: 无法解析类型的任何 bean:类 app.DemoApplication; 限定符:[@javax.enterprise.inject.Any()] 在 org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:101) 在 app.Main.main(Main.java:14)
有问题的代码通过 Weld 容器实例化以支持 CDI,并且非常基础:
package app;
import javax.inject.Inject;
import javax.persistence.EntityManager;
public class DemoApplication {
@Inject private EntityManager em;
public void run() {
try {
em.getTransaction().begin();
System.out.println("Inside transaction");
} catch (Throwable t) {
t.printStackTrace();
} finally {
em.getTransaction().rollback();
em.close();
}
}
}
我在这里遗漏了一个明显的观点吗?如何让 Weld 发现注入依赖项的生产者方法?
我已经在Github 上建立了一个最小的项目来重现我的问题。感谢您提供任何有用的建议! :)
2015-05-18 更新:
好像我误解了错误信息。事实上,Weld 甚至没有解析 DemoApplication bean,这让我相信 bean 发现过程有问题。在将我的weld-se 依赖项更新到新发布的3.0.0.Alpha8 版本(请参阅链接的Github 存储库)后,我能够通过在Main.java 中手动告诉Weld 我的bean 来让应用程序工作:
final Weld weld = new Weld()
.enableDiscovery()
.addPackage(false, HibernateUtil.class)
.addPackage(false, DemoApplication.class);
尽管如此,对于尽管有一个空的 META-INF/beans.xml 并没有自动发现 bean 的任何建议,我们都非常感谢!
2015-05-19 更新:
谜团已解开,请看下面我自己的答案。我更改了问题标题,以反映问题的实际性质。
【问题讨论】:
-
您的
beans.xml中的bean-discovery-mode是什么? -
@MilanBaran 我尝试使用一个空 beans.xml,以及一个带有
bean-discovery-mode=ALL的文件,两者都没有任何可见效果。
标签: java gradle jboss-weld weld-se