No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 0

Kapaacius picture Kapaacius · Apr 15, 2013 · Viewed 7.6k times · Source

I have a problem with my spring security/hibernate app, which i can't resolve, since i'm new to spring and also hibernate. Here's my problem:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userAccountService': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 0: 
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:343)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:647)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:598)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:661)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:517)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:458)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:138)
    at javax.servlet.GenericServlet.init(GenericServlet.java:241)
    at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:440)
    at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:263)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:736)
    at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
    at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1282)
    at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:518)
    at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:499)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
    at org.mortbay.jetty.Server.doStart(Server.java:224)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at runjettyrun.Bootstrap.main(Bootstrap.java:97)
2013-04-15 14:39:30.076:INFO::Started [email protected]:8080

I can't figure out what's the problem there. I have googled it and tried some solutions that may have helped others, but my error keeps poping up. Since i'm new to spring it's probably some simple error i'm making in my code. :)

web.xml

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext-security.xml</param-value>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- Spring Security -->
  <filter>
      <filter-name>springSecurityFilterChain</filter-name>
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter> 
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <welcome-file-list>
    <welcome-file>jsp/index.jsp</welcome-file>
  </welcome-file-list>

</web-app>

applicationContext.xml

    <beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/security
            http://www.springframework.org/schema/security/spring-security-3.1.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <mvc:annotation-driven />

    <http auto-config="true">
        <form-login login-page="/login" default-target-url="/" authentication-failure-url="/loginfailed" />
        <logout logout-success-url="/logout" />
        <intercept-url pattern="/admin" access="ROLE_ADMIN" />
        <intercept-url pattern="/" access="ROLE_USER,ROLE_ADMIN" />
    </http>

    <beans:bean id="loginService" class="fishpoop.services.LoginService" />

    <authentication-manager>
        <authentication-provider user-service-ref="loginService">
        </authentication-provider>
    </authentication-manager>

</beans:beans>

hibernateContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <context:property-placeholder location="/WEB-INF/jdbc.properties" />

    <tx:annotation-driven transaction-manager="transactionManager" />

    <!-- Declare a datasource that has pooling capabilities-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
          destroy-method="close"
          p:driverClass="${jdbc.driverClassName}"
          p:jdbcUrl="${jdbc.url}"
          p:user="${jdbc.username}"
          p:password="${jdbc.password}"
          p:acquireIncrement="5"
          p:idleConnectionTestPeriod="60"
          p:maxPoolSize="100"
          p:maxStatements="50"
          p:minPoolSize="10" />

    <!-- Declare a JPA entityManagerFactory-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
        <property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
        <property name="persistenceUnitName" value="hibernatePersistenceUnit" />
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" >
                <property name="showSql" value="true"/>
            </bean>
        </property>
    </bean>

    <!-- Declare a transaction manager-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

</beans>

UserAccountService.java

package fishpoop.services;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import fishpoop.model.UserAccount;

@Service("userAccountService")
@Transactional
public class UserAccountService {

    private EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager){ 
            this. entityManager = entityManager; 
        }
    public UserAccount get(Integer id)
    {
        Query query = entityManager.createQuery("FROM user_account as ua WHERE ua.id="+id);
        return (UserAccount) query.getSingleResult();
    }

    public UserAccount get(String username)
    {
        Query query = entityManager.createQuery("FROM user_account as ua WHERE ua.username='"+username+"'");
        return (UserAccount) query.getSingleResult();
    }

    public void add(UserAccount userAccount)
    {
        entityManager.persist(userAccount);
    }
}

Can anybody help me with this error?

Answer

Ori Dar picture Ori Dar · Apr 15, 2013

It seems that you you have files name mismatch here:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-security.xml</param-value>
<param-value>/WEB-INF/applicationContext.xml</param-value>

In contracts, you have mentioned applicationContext.xml and hibernateContext.xml

Anyway param-value should only appear once such as:

 <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/hibernateContext.xml /WEB-INF/applicationContext.xml
</param-value>

Note the space between the two values inside param-value tag

The fact that Spring is booted, and located your Service class (via <mvc:annotation-driven />) suggests that it's using the first xml file , but not the second one