I am building a Gradle-based Java SE application built on top of Hibernate as my ORM of choice. My plan is to use weld-se
to be able to use CDI annotations for injections of EntityManagers
throughout the application.
Based on the common HibernateUtil
helper class found in the Hibernate documentation, I moved towards JPA interfaces and added @Produces
annotations to provide producer methods (I have added an empty META-INF/beans.xml
as well):
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();
}
}
}
When I try to use the @Inject
annotation on a field, however, Weld fails to resolve the correct producer method and produces an exception instead:
Exception in thread "main" org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308: Unable to resolve any beans for Type: class app.DemoApplication; Qualifiers: [@javax.enterprise.inject.Any()] at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:101) at app.Main.main(Main.java:14)
The offending code is instantiated through the Weld container for CDI support and is incredibly basic:
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();
}
}
}
Am I missing an obvious point here? How can I get Weld to discover the producer method for injecting my dependencies?
I have put together a minimal project reproducing my problem on Github. Thanks for any helpful suggestions! :)
Update 2015-05-18:
Seems like I misunderstood the error message. In fact, Weld does not even resolve the DemoApplication
bean, which leads me to believe, that something's wrong with the bean discovery process. After updating my weld-se dependency to the freshly released 3.0.0.Alpha8 version (see the linked Github repo), I was able to get the application to work by manually telling Weld about my beans in Main.java
:
final Weld weld = new Weld()
.enableDiscovery()
.addPackage(false, HibernateUtil.class)
.addPackage(false, DemoApplication.class);
Still, any suggestions as to why the beans are not automatically discovered despite having an empty META-INF/beans.xml
in place are highly appreciated!
Update 2015-05-19:
The mystery is unraveled, see my own answer below. I changed the question title, in order to reflect the actual nature of the issue.
bean-discovery-mode
in yourbeans.xml
? – Raleighraleybean-discovery-mode=ALL
, both without any visible effect. – Wildebeest