【问题标题】:Why is my Spring data configuration not autowiring a repository interface?为什么我的 Spring 数据配置没有自动装配存储库接口?
【发布时间】:2015-05-01 15:48:47
【问题描述】:

首先,我想欢迎大家,虽然我是新成员,但我是一个经常匿名的用户,在这里寻找我的问题的可能答案:)

我的 Spring Data 配置有一个非常复杂的问题,我已经为此奋斗了 2 天,现在我想到了可能性;/ 我之前已经创建了具有 Spring Data JPA 功能的项目,并且没有像现在这样遇到那么多问题......;/ 在这个过程中,我研究了多个网站,并对我的配置进行了一些更改,但没有任何帮助;/

在我的 spring 配置 xml 文件中,我创建了以下 bean:BasicDataSource、LocalContainerEntityManagerFactoryBean 和一个 JpaTransactionManager。 顺便提一句: 我正在使用 Spring 4.1.6、Spring Data 版本 1.8.0 和休眠 4.3.8.Final

这是 Spring 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:repository="http://www.springframework.org/schema/data/repository"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
        http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository-1.7.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <context:component-scan base-package="pl.mmalik.portlet.common.model" />
    <context:component-scan base-package="pl.mmalik.portlet.common.service" />

    <context:annotation-config />

    <context:property-placeholder location="classpath:springData/dataSource.properties"/> 

    <util:properties id="hibernateProperties" location="classpath:springData/hibernate.properties"/>

    <bean id="lifeRayDataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="${connection.driverClassName}"/>
        <property name="url" value="${connection.url}"/>
        <property name="username" value="${db.username}"/>
        <property name="password" value="${db.password}"/>
        <property name="maxActive" value="128"/>
        <property name="maxIdle" value="64"/>
        <property name="minIdle" value="24"/>
        <property name="validationQuery" value="SELECT 1 FROM DUAL"/>
    </bean>

    <bean id="entityManagerFactory" 
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="lifeRayDataSource"/>
        <property name="packagesToScan">
            <list>
                <value>pl.mmalik.portlet.common.domain.model</value>
            </list>
        </property>
        <property name="persistenceUnitName" value="LIFE-RAY-PU" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <property name="jpaProperties" ref="hibernateProperties"/>
    </bean>

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

    <jpa:repositories
            base-package="pl.mmalik.portlet.common.respository"
            entity-manager-factory-ref="entityManagerFactory"
            transaction-manager-ref="transactionManager" />

</beans>

我正在尝试创建一个 JpaRepository 接口来处理实体上的基本数据库操作。

实体如下:

@Entity
@Table(name = "Recipie")
public class Recipie {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "RecipiSeq")
    @SequenceGenerator(initialValue = 1,
                        name = "RecipiSeq",
                        sequenceName = "RecipiSeq",
                        allocationSize = 1)
    @Column(name = "RECIPIE_ID", unique = true)
    private Integer recipieId;

    @NotNull
    @Column(name = "RECIPIE_NAME")
    private String name;

    @NotNull
    @Column(name="RECIP_CAT")
    private String category;

    @NotNull
    @Size(max = 255)
    @Column
    private String description;

    @Digits(fraction = 0, integer = 3)
    @Column(name = "READY_IN")
    private Integer readyIn;

    @Column
    private String author;

    @Column(name="iconFile")
    private byte[] file;

    public Recipie() {
    }

    // Setters and getters are here...
}

Repository 是一个扩展 JpaRepository 的小接口,

public interface RecipieRepository extends JpaRepository<Recipie, Integer>{

}

在部署时,我得到一个带有以下堆栈跟踪的“NoSuchBeanDefinitionException”:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'recipieMock': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private pl.mmalik.portlet.common.repositories.RecipieRepository pl.mmalik.portlet.common.domain.model.mock.RecipieMock.recipieRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [pl.mmalik.portlet.common.repositories.RecipieRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.web.portlet.FrameworkPortlet.createPortletApplicationContext(FrameworkPortlet.java:368)
    at org.springframework.web.portlet.FrameworkPortlet.initPortletApplicationContext(FrameworkPortlet.java:297)
    at org.springframework.web.portlet.FrameworkPortlet.initPortletBean(FrameworkPortlet.java:271)
    at org.springframework.web.portlet.GenericPortletBean.init(GenericPortletBean.java:124)
    at javax.portlet.GenericPortlet.init(GenericPortlet.java:107)
    at com.liferay.portlet.InvokerPortletImpl.init(InvokerPortletImpl.java:269)
    at com.liferay.portlet.PortletInstanceFactoryImpl.init(PortletInstanceFactoryImpl.java:228)
    at com.liferay.portlet.PortletInstanceFactoryImpl.create(PortletInstanceFactoryImpl.java:145)
    at com.liferay.portlet.PortletInstanceFactoryUtil.create(PortletInstanceFactoryUtil.java:41)
    at com.liferay.portlet.PortletBagFactory.create(PortletBagFactory.java:337)
    at com.liferay.portal.deploy.hot.PortletHotDeployListener.doInvokeDeploy(PortletHotDeployListener.java:370)
    at com.liferay.portal.deploy.hot.PortletHotDeployListener.invokeDeploy(PortletHotDeployListener.java:125)
    at com.liferay.portal.deploy.hot.HotDeployImpl.doFireDeployEvent(HotDeployImpl.java:227)
    at com.liferay.portal.deploy.hot.HotDeployImpl.fireDeployEvent(HotDeployImpl.java:96)
    at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil.java:28)
    at com.liferay.portal.kernel.servlet.PluginContextListener.fireDeployEvent(PluginContextListener.java:164)
    at com.liferay.portal.kernel.servlet.PluginContextListener.doPortalInit(PluginContextListener.java:154)
    at com.liferay.portal.kernel.util.BasePortalLifecycle.portalInit(BasePortalLifecycle.java:44)
    at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:74)
    at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:58)
    at com.liferay.portal.kernel.util.BasePortalLifecycle.registerPortalLifecycle(BasePortalLifecycle.java:54)
    at com.liferay.portal.kernel.servlet.PluginContextListener.contextInitialized(PluginContextListener.java:116)
    at com.liferay.portal.kernel.servlet.SecurePluginContextListener.contextInitialized(SecurePluginContextListener.java:151)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3954)
    at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
    at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
    at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private pl.mmalik.portlet.common.repositories.RecipieRepository pl.mmalik.portlet.common.domain.model.mock.RecipieMock.recipieRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [pl.mmalik.portlet.common.repositories.RecipieRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 44 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [pl.mmalik.portlet.common.repositories.RecipieRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 46 more

我认为这与我对 EntityManager 或 DataSource 的配置有关,但研究这些元素的其他配置选项并没有给我带来任何好处;/

我将非常感谢任何建议,我完全坚持这一点。 如果您需要有关配置的任何其他信息,我将更新此帖子。

【问题讨论】:

    标签: java hibernate repository spring-data-jpa autowired


    【解决方案1】:

    如果问题与 DataSource 或 EntityManager 有关,您将收到一条消息,通知您这些问题存在。但你没有。你得到的消息是

    No qualifying bean of type [pl.mmalik.portlet.common.repositories.RecipieRepository] found
    

    这意味着 Spring 找不到任何实现此接口的 Spring bean。你是否配置了 Spring 来扫描那个包?

    <jpa:repositories
            base-package="pl.mmalik.portlet.common.respository"
    

    不,你没有。

    【讨论】:

    • 其实在配置文件的最底部有一个 jpa:repositories 标签。
    • 这是我的观点:基础包与存储库接口的包不匹配
    【解决方案2】:

    您的接口“RecipieRepository”似乎没有实现,但在您的代码中某处您使用了@Autowired 提交到该“接口”,例如

    @Autowired
    private RecipieRepository recipieMock;
    

    它会失败,因为您至少需要一个实现来自动连接。

    要解决此问题,请创建一个实现您的存储库“RecipieRepository”的“类”,并为其添加以下注释。

    @Repository
    @Transactional
    @Component
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-30
      • 2019-02-28
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      • 1970-01-01
      • 2012-10-05
      • 2015-09-18
      相关资源
      最近更新 更多