title: Spring Boot Test: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
body: <p>I am trying to set up a test context under spring boot, so I defined a TestApplicationContext like so:</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @SpringApplicationConfiguration(classes = {MvcConfig.class,SecurityConfig.class})
  @WebAppConfiguration
  @EnableAutoConfiguration
  @PropertySource({ "classpath:persistence.properties" })
  @ComponentScan
  public class TestApplicationContext {
  
      @Autowired
      private Environment env;
  
      @Bean
      public EmbeddedServletContainerFactory servletContainer() {
          TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
          factory.setPort(9000);
          factory.setSessionTimeout(10, TimeUnit.MINUTES);
          //factory.addErrorPages(new ErrorPage(HttpStatus.404, "/notfound.html"));
          return factory;
      }
  
      @Bean
      public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(emf);
      return transactionManager;
      }
  
  
      @Bean
      public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
         LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
         em.setDataSource(hsqlDataSource());
         em.setPackagesToScan(new String[] { "com.touchcorp.touchppoint.model" });
  
         JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
         em.setJpaVendorAdapter(vendorAdapter);
         em.setJpaProperties(buildHibernateProperties());
  
         return em;
      }
  
      @Bean
      public DataSource hsqlDataSource()
      {
          BasicDataSource basicDataSource = new BasicDataSource();
          basicDataSource.setDriverClassName(org.hsqldb.jdbcDriver.class.getName());
          basicDataSource.setUsername("sa");
          basicDataSource.setPassword("");
          basicDataSource.setUrl("jdbc:hsqldb:mem:mydb");
          return basicDataSource;
      }
  
      /**
       *
       * Loading all the hibernate properties from a properties file
       */
      protected Properties buildHibernateProperties()
      {
          Properties hibernateProperties = new Properties();
  
          hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
          hibernateProperties.setProperty("hibernate.show_sql", "true");
          hibernateProperties.setProperty("hibernate.use_sql_comments", "true");
          hibernateProperties.setProperty("hibernate.format_sql", "true");
          hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
  
          hibernateProperties.setProperty("hibernate.generate_statistics", env.getProperty("hibernate.generate_statistics"));
  
          hibernateProperties.setProperty("javax.persistence.validation.mode", env.getProperty("javax.persistence.validation.mode"));
  
          //Audit History flags
          hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", env.getProperty("org.hibernate.envers.store_data_at_delete"));
          hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", env.getProperty("org.hibernate.envers.global_with_modified_flag"));
  
          return hibernateProperties;
      }
  
  }
  </code></pre>
  
  <p>Which is attempting to set up its own persistence context, so I can run a test like this:</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  public class ApplicationIntegrationTest extends TestApplicationContext {
  
      MockMvc mockMvc;
  
      @Autowired
      private WebApplicationContext wac;
  
      @Resource(name="springSecurityFilterChain")
      private FilterChainProxy springSecurityFilterChain;
  
      @Before
      public void setup() {
          // using the web application to initiate the mock
          mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilter(springSecurityFilterChain).build();
  
  
      }
  
      @Test
      public void thatViewBootstrapUsesHttpNotFound() throws Exception {
  
          MvcResult result = mockMvc.perform(post("/login")
                  .param("username", "user").param("password", "password")).andReturn();
          Cookie c = result.getResponse().getCookie("my-cookie");
          assertThat(c.getValue().length(), greaterThan(10));
  
          // No cookie; 401 Unauthorized
          mockMvc.perform(get("/")).andExpect(status().isUnauthorized());
  
          // With cookie; 200 OK
          mockMvc.perform(get("/").cookie(c)).andExpect(status().isOk());
  
          // Logout, and ensure we're told to wipe the cookie
          result = mockMvc.perform(delete("/session")).andReturn();
          c = result.getResponse().getCookie("my-cookie");
          assertThat(c.getValue().length(), is(0));
      }
  
  }
  </code></pre>
  
  <p>Now this is all backed by a hibernate HSQLDB userDao, which is called by a DeviceUsernamePasswordAuthenticationProvider</p>
  
  <pre><code>@Service(value="customAuthenticationProvider")
  public class DeviceUsernamePasswordAuthenticationProvider implements AuthenticationProvider {
      private static final Logger LOG = LoggerFactory.getLogger(DeviceUsernamePasswordAuthenticationProvider.class);
  
      @Autowired
      private CustomUserDetailsService customUserDetailsService;
  
      @Autowired
      private DeviceDetailsService deviceDetailsService;
  
      @Override
      public boolean supports(Class&lt;? extends Object&gt; authentication) {
          return authentication.equals(DeviceUsernamePasswordAuthenticationToken.class);
      }
  
      /**
       * Implements authentication with a number of scenarios in mind:
       * &lt;ul&gt;
       *     &lt;li&gt;A non-browser client is making a request without device details - FAIL&lt;/li&gt;
       *     &lt;li&gt;A non-browser client is making a request with device details in the request  - CHECK
       *     if successful a TOKEN is set&lt;/li&gt;
       *     &lt;li&gt;A non-browser client is making a request with device TOKEN  - CHECK&lt;/li&gt;
       *     &lt;li&gt;A browser client is making a request with device TOKEN or device details with user and password  - CHECK
       *     if successful JSESSIONID is set&lt;/li&gt;
       * &lt;/ul&gt;
       * @param authentication
       * @return
       * @throws AuthenticationException
       */
      @Override
      public Authentication authenticate(Authentication authentication) throws AuthenticationException {
  
          LOG.info("Authenticating device and user - assigning authorities...");
          DeviceUsernamePasswordAuthenticationToken auth = (DeviceUsernamePasswordAuthenticationToken) authentication;
          String name = auth.getName();
          String password = auth.getCredentials().toString();
  
          boolean isDeviceRequest = (name == null &amp;&amp; password == null);
          LOG.debug("name is {}, password is {}", name, password);
  
          // (a) nothing, (b) hasToken|&lt;token encoding&gt;, or (c) getToken|&lt;base64 encoded device request&gt;
          String deviceToken = auth.getDeviceAuthorisation();
  
          if (deviceToken == null) {
              // very bad - set as anonymous
              LOG.error("missing.device.token");
              throw new BadCredentialsException("missing.device.token");
          }
  
          LOG.debug("deviceToken is {}", deviceToken);
          String[] deviceInformation = StringUtils.split(deviceToken,"|");
  
  
          DeviceDetails device = null;
  
          if(deviceInformation[0].equals("getToken")) {
              LOG.debug("getToken");
              // we expect the array to be of length 3, if not, the request is malformed
              if (deviceInformation.length &lt; 3) {
                  LOG.error("malformed.device.token");
                  throw new BadCredentialsException("malformed.device.token");
              }
  
              device = deviceDetailsService.loadDeviceByDeviceId(deviceInformation[1]);
  
              if (device == null) {
                  LOG.error("missing.device");
                  throw new BadCredentialsException("missing.device");
              } else {
                  // otherwise, get the authorities
                  auth = new DeviceUsernamePasswordAuthenticationToken(null, null,
                          device.getDeviceId(), device.getAuthorities());
  
                  //also we need to set a new token into the database
  
                  String newToken = Hashing.sha256()
                          .hashString("your input", Charsets.UTF_8)
                          .toString();
  
  
                  deviceDetailsService.setToken(device.getDeviceId(),newToken);
  
                  // and put it into the response headers
                  auth.setDeviceTokenForHeaders(newToken);
  
              }
          } else if(deviceInformation[0].equals("hasToken")) {
              LOG.debug("hasToken");
              if (deviceInformation.length &lt; 3) {
                  LOG.error("malformed.device.token");
                  throw new BadCredentialsException("malformed.device.token");
              }
  
              // check that there is a token and that the token has not expired
              String token = deviceDetailsService.getToken(deviceInformation[1]);
  
              if (token == null) {
                  // we got a token in the request but the token we have no stored token
                  LOG.error("mismatched.device.token");
                  throw new BadCredentialsException("mismatched.device.token");
              } else if(!token.equals(deviceInformation[2])) {
                  // we got a token in the request and its not the same as the token we have stored
                  LOG.error("mismatched.device.token");
                  throw new BadCredentialsException("mismatched.device.token");
              } else if ( deviceDetailsService.hasTokenExpired(deviceInformation[1])) {
                  // we got a token in the request and its not the same as the token we have stored
                  LOG.error("expired.device.token");
                  throw new BadCredentialsException("expired.device.token");
              } else {
                  // token was in the request, correctly formed, and matches out records
                  device = deviceDetailsService.loadDeviceByDeviceId(deviceInformation[1]);
                  auth = new DeviceUsernamePasswordAuthenticationToken(null, null,
                          device.getDeviceId(), device.getAuthorities());
              }
  
  
          } else {
              LOG.error("malformed.device.token");
              throw new BadCredentialsException("malformed.device.token");
          }
  
          if (!isDeviceRequest) {
  
              // OK, now we can do the user stuff
  
  
  
  
              UserDetails user = customUserDetailsService.loadUserByUsername(name);
              auth = new DeviceUsernamePasswordAuthenticationToken(name, password, device.getDeviceId(), device.getAuthorities());
          }
  
          return auth;
      }
  
  }
  </code></pre>
  
  <p>which uses a CustomUserDetailsService like so:</p>
  
  <pre><code>@Service(value="customUserDetailsService")
  @Transactional(readOnly=true)
  public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
  
      private static final Logger LOG = LoggerFactory.getLogger(CustomUserDetailsServiceImpl.class);
  
      @Autowired
      private UserDao userDao;
  
  
  
      public UserDetails loadUserByUsername(String login)
              throws UsernameNotFoundException {
          LOG.info("Finding the UserDetails for {}", login);
  
          com.touchcorp.touchpoint.model.domain.User domainUser = userDao.getUser(login);
  
          if(domainUser == null) {
              throw new UsernameNotFoundException("The user {} was not found", login);
          }
  
          boolean enabled = true;
          boolean accountNonExpired = true;
          boolean credentialsNonExpired = true;
          boolean accountNonLocked = true;
  
          return new User(
                  domainUser.getLogin(),
                  domainUser.getPassword(),
                  enabled,
                  accountNonExpired,
                  credentialsNonExpired,
                  accountNonLocked,
                  getAuthorities(domainUser.getRoles())
          );
      }
  
  
      public Collection&lt;? extends GrantedAuthority&gt; getAuthorities(List&lt;Role&gt; roles) {
          List&lt;GrantedAuthority&gt; authorities = new ArrayList&lt;&gt;();
          LOG.debug("List of Authorities...");
          for (Role role : roles) {
  
              StringBuilder bob = new StringBuilder("ROLE_");
              bob.append(role.getRole().toUpperCase());
              LOG.debug("authority {}",bob.toString());
              authorities.add(new SimpleGrantedAuthority(bob.toString()));
          }
  
          return authorities;
      }
  
  }
  </code></pre>
  
  <p>Which calls on the userDao..</p>
  
  <pre><code>@Repository("userDao")
  public class UserDaoImpl implements UserDao {
      private static final Logger LOG = LoggerFactory.getLogger(UserDaoImpl.class);
  
      @PersistenceContext
      private EntityManager entityManager;
  
      public User getUser(String login) {
          LOG.debug("Looking for a user with login: {}", login);
  
          List&lt;User&gt; list = entityManager.createQuery(
                                  "SELECT u FROM User u WHERE u.login = :login")
                          .setParameter("login", login).getResultList( );
                  return (list.isEmpty( )?null:list.get( 0 ));
      }
  
  }
  </code></pre>
  
  <p>The problem is that the container won't start up, and instead throws the evil BeanCreationException.</p>
  
  <p>Here's the stack trace stepping through the various layers</p>
  
  <pre><code>Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customAuthenticationProvider': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.touchcorp.touchpoint.service.CustomUserDetailsService com.touchcorp.touchpoint.security.DeviceUsernamePasswordAuthenticationProvider.customUserDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customUserDetailsService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.touchcorp.touchpoint.model.dao.UserDao com.touchcorp.touchpoint.service.CustomUserDetailsServiceImpl.userDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
      ... 45 more
  Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.touchcorp.touchpoint.service.CustomUserDetailsService com.touchcorp.touchpoint.security.DeviceUsernamePasswordAuthenticationProvider.customUserDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customUserDetailsService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.touchcorp.touchpoint.model.dao.UserDao com.touchcorp.touchpoint.service.CustomUserDetailsServiceImpl.userDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
      at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
      ... 56 more
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customUserDetailsService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.touchcorp.touchpoint.model.dao.UserDao com.touchcorp.touchpoint.service.CustomUserDetailsServiceImpl.userDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
      ... 58 more
  Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.touchcorp.touchpoint.model.dao.UserDao com.touchcorp.touchpoint.service.CustomUserDetailsServiceImpl.userDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
      at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
      ... 69 more
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
      at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:356)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
      ... 71 more
  Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
      at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:559)
      at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:515)
      at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:682)
      at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:655)
      at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:155)
      at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
      at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:353)
      ... 82 more
  </code></pre>
  
  <p>Does anyone know what I am missing here?</p>