1

I am running a Spring rest app that is a console app. I'm using spring-boot which embeds tomcat 7.

When I boot the app, I get a stack trace and dumped out. Here's the root cause:

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.jav
a:559)
        at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:515)
        at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProce
ssor.java:682)
        at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProces
sor.java:655)
        at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
        at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:353)

        ... 22 more

Here's where I start my Application:

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Here's my /src/main/resources/spring-config.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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/tx  
           http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="com.mydomain.orm" />

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:/persistence.xml" />
        <property name="persistenceUnitName" value="userPersistenceUnit" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
        <property name="jpaDialect" ref="jpaDialect" />
    </bean>

    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="database" value="POSTGRESQL" />
        <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
    </bean>

    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaDialect" ref="jpaDialect" />
    </bean>

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

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://localhost:5432/mydb" />
        <property name="username" value="myuser" />
        <property name="password" value="" />
    </bean>
</beans> 

Here's my DAO:

@Repository("userDao")
@Transactional(propagation = Propagation.REQUIRED)
public class UserDAO {

    private static final String SELECT_QUERY = "select u from users";

    @PersistenceContext
    private EntityManager entityManager;

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public void insert(User user) {
        entityManager.persist(user);
    }

    public User load(int id) {
        return entityManager.find(User.class, id);
    }

    public List<User> selectAll() {
        Query query = entityManager.createQuery(SELECT_QUERY);
        @SuppressWarnings("unchecked")
        List<User> users = (List<User>) query.getResultList();
        return users;
    }
}

And my /src/main/persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <persistence-unit name="userPersistenceUnit" transaction-type="RESOURCE_LOCAL" >
        <class>com.mydomain.orm.User</class>
    </persistence-unit>
</persistence> 
Lurk21
  • 2,307
  • 12
  • 37
  • 55
  • Please show us where you are loading your `spring-config.xml`. – Sotirios Delimanolis Dec 28 '13 at 02:34
  • @SotiriosDelimanolis I'm not explicitly loading it, I was under the impression that it would load if it was in my classpath. It's in /src/main/resources. – Lurk21 Dec 28 '13 at 03:54
  • I don't know what strategies spring-boot uses to load springs contexts but I can guarantee you it doesn't load all `.xml` files it finds. If there's a naming convention, maybe. In your case, it doesn't seem like the context is loaded. You can make sure by trying to inject the other beans declared there, eg. `dataSource`. – Sotirios Delimanolis Dec 28 '13 at 03:56
  • Show us where you start your `Application`. – Sotirios Delimanolis Dec 28 '13 at 03:57
  • @SotiriosDelimanolis I updated the spring-config, added a persistence.xml, and also edited this question to include where I start my Application – Lurk21 Dec 28 '13 at 04:11
  • This was answered here: http://stackoverflow.com/questions/20808290/spring-jpa-hibernate-no-qualifying-bean-of-type-javax-persistence-entitymanag – Lurk21 Jan 02 '14 at 20:18
  • Glad you found it. Your context simply wasn't loaded. – Sotirios Delimanolis Jan 02 '14 at 20:22

2 Answers2

0

If you're going to use @PersistenceContext, you're required to set up persistence.xml for your use case, since that annotation effectively tells Spring, "Use the Java EE way of setting up JPA, not the Spring/Hibernate way." Keep in mind that Tomcat is not a Java EE container, so it may not work right.. Spring Boot is pretty new, though, so it's possible that there is a way to do this that might not yet be well-documented.

I'd start with setting up persistence.xml and see what happens.

Community
  • 1
  • 1
Brad
  • 2,261
  • 3
  • 22
  • 32
  • I setup my persistence.xml and the situation is unchanged. I had started to worry about that possible lack of Java EE... I had all of this working with by-the-book Hibernate on Question http://stackoverflow.com/questions/20804768/spring-restful-controller-method-improvement-suggestions but started down this road after receiving the suggestion to switch to this approach. – Lurk21 Dec 28 '13 at 04:15
  • Just for the heck of it, have you tried directly @Autowiring in the EMF, just to see if Spring finds it at all? – Brad Dec 28 '13 at 16:52
0

SO keeps telling me that this is a trivial answer and converting it to a comment, so here's a long line in hopes of convincing SO that this is not a trivial answer, but in fact a lot of work went into it.

Look here for the answer: Spring JPA (Hibernate) No qualifying bean of type: javax.persistence.EntityManagerFactory

Community
  • 1
  • 1
Lurk21
  • 2,307
  • 12
  • 37
  • 55
  • 5
    SO is telling you that, because you're supposed to close your question as a duplicate, instead of posting an answer, which only contains a link. – Tom Aug 09 '16 at 13:22