Question

I'd like to make use of spring-data-jpa and CrudRepository<T, ID extends Serializable>. But I cannot get it autowired. (all other services in the same package are wired correctly):

@Service
public class UserService {
    @Resource
    private UserRepo repo;

    //this does neither work
    //@Autowired
    //private CrudRepository<User, Long> repo;

}

public interface UserRepo extends CrudRepository<User, Long> {

}

@Entity
public class User {
    @Id
    private Long id;
} 

Result:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [UserRepo] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, lookup=, authenticationType=CONTAINER)}

What might be wrong here?

From the docs I think it should work without writing an implementation:

In a typical Java application, you’d expect to write a class that implements CustomerRepository. But that’s what makes Spring Data JPA so powerful: You don’t have to write an implementation of the repository interface. Spring Data JPA creates an implementation on the fly when you run the application.


Updated SpringConfig:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("my.package")
public class AppConfig {

    @Bean
    public LocalContainerEntityManagerFactoryBean emf() throws ClassNotFoundException, PropertyVetoException {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(dataSource());
        emf.setPackagesToScan("my.package");
        emf.setJpaVendorAdapter(jpaAdapter());
        emf.setJpaProperties(jpaProterties());
        return emf;
    }
}

Result: emf is missing, which is strange as I already have working DAO serices where I can autowire EntityManager and EMF without any problem.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1a6e658': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:336)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:632)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:442)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:276)
    ... 50 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:641)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1159)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:282)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    ... 58 more
Was it helpful?

Solution

You should verify the following:

1) Annotate the UserRepo with @Repository.

2) Your spring beans xml file should have in it:

<jpa:repositories base-package="your.repository.package"></jpa:repositories>

3) I'd recommend injecting this type of bean with @Autowired instead of @Resource

UPDATE

it seems you did my first 3 steps and you're one step ahead now. Now, remember that in Java Config methods names DO matter. Either change emf() to entityManagerFactory() (which is more "standard"), or set entity-manager-factory-ref to emf. Example:

@Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException, PropertyVetoException {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(dataSource());
        emf.setPackagesToScan("my.package");
        emf.setJpaVendorAdapter(jpaAdapter());
        emf.setJpaProperties(jpaProterties());
        return emf;
    }

OTHER TIPS

Doesn't UserRepo needs to be annotated with :

 @Repository

It must be an issue in your applicationContext configuration. Here is the one I used to made it work:

<jpa:repositories
    base-package="package.containing.your.repositories"
    factory-class="org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean"
    transaction-manager-ref="transactionManager"
    entity-manager-factory-ref="entityManagerFactory" />

<bean
    id="transactionManager"
    class="org.springframework.orm.jpa.JpaTransactionManager"
    p:entityManagerFactory-ref="entityManagerFactory" />

<bean
    id="hibernateJpaVendorAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />

<bean
    id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    p:dataSource-ref="dataSource"
    p:persistenceUnitName="PU"
    p:jpaVendorAdapter-ref="hibernateJpaVendorAdapter"
    p:jpaProperties="classpath:hibernate.properties" />

<util:property-path id="sessionFactory" path="entityManagerFactory.sessionFactory" />

Configuring spring data JPA using XML and annotations

//This is the two way to configure spring data JPA
    @EnableJpaRepositories (basePackages= "Repository Bean is located in package", entityManagerFactoryRef= "Here is your configuration of EntityManagerFactoryBean")

    <jpa:repositories base-package= "Repository Bean where package"
    Entity-manager-factory-ref= "Here is your configured EntityManagerFactoryBean" ></jpa:repositories>
   // Sample code:
   @Configuration
   @EnableTransactionManagement
   @EnableJpaRepositories(basePackages="com.zxg.springdata", 
                  entityManagerFactoryRef="factoryBean")
  public class SpringDataConfig {
    @Bean
    public LocalContainerEntityManagerFactoryBean factoryBean (
      ComboPooledDataSource dataSource, JpaVendorAdapter jpaVendorAdapter
      ){
         LocalContainerEntityManagerFactoryBean factoryBean = new 
                LocalContainerEntityManagerFactoryBean ();
         FactoryBean.setDataSource (dataSource);
         FactoryBean.setJpaVendorAdapter (jpaVendorAdapter);
         FactoryBean.setPackagesToScan ("com.zxg.springdata");
         Return factoryBean;
       }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top