I'm trying to write a web application that will run on Tomcat 8 using Spring MVC 4, Hibernate and JPA.
I'm doing this annotation driven so no XML in the Spring code if I can help it.
I have several layers in the application: Controllers that are part of the Spring MVC web app; services and repositories (although these are not annotated as Spring services etc.), all are in different JAR files that are distributed in the web app's WAR.
I'd like to inject either EntityManager or EntityManagerFactory into my code (I'm using a variation of the repository pattern) but can't get it to work.
I also have a persistence.xml defined that sets up a persistence unit.
I've tried several things and nothing works.
I've added @PersistenceContext to both an EntityManager and EntityManagerFactory variable;
I've tried @PersistenceUnit in the repository code but no luck.
The last thing I tried (following this post Injecting EntityManager with a producer in tomcat) was to add a listener to the web app and use @Inject in my code. The listener is created but the 'createEntityManager' method is never called (and yes, I've changed it to add the @Produces annotation)
So my listener looks like this:
@Produces
public EntityManager createEntityManager() {
System.out.println("*********** EntityManagerFactoryListener - createEntityManager: ");
if (entityManagerFactory == null) {
throw new IllegalStateException("Context is not initialized yet.");
}
return entityManagerFactory.createEntityManager();
}
And my reoository looks like this
@Inject
public void setEntityManager(final EntityManager entityManager) {
this.entityManager = entityManager;
System.out.println("*********** entityManager: " + entityManager);
}
The error I get is
Error creating bean with name 'hibernateRepository': Injection of autowired dependencies failed
...
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManager] ...
Am I missing something? Can I even do this in Tomcat or do I need an EJB container?
EDIT
In answer to the question I have a WebApplictionInitializer that looks like this:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context) );
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
private WebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConfig.class);
return context;
}
and a WebMvcConfigurerAdapter that looks like:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.pluralsight")
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
}