1

リポジトリファクトリBeanによって作成されたリポジトリを自動配線しようとしています。特定のリポジトリのsave()メソッドをカスタムコードでオーバーライドする必要があります。Spring Dataの紹介で、ファクトリBeanの例に従いました。

しかし、私が何をするにしても、私は得ていNoSuchBeanDefinitionExceptionます。

一方、「インターフェースのみのリポジトリ」は問題なく作成され、注入されます。

どこかでばかげた間違いをしている可能性が非常に高いです。これはSpringData101であると想定されているためです。

誰かが私にそれを機能させるために他に何をしようとしているのかについての手がかりを教えてもらえますか?

スペック

Hibernate4.1.9。ファイナル

春3.2.1。リリース

春のデータ1.3.0.RELEASE

JDK1.6.0_39。

Arch Linux x64

リポジトリファクトリ

エンティティのタイプがBarの場合、別のリポジトリを返します。それ以外の場合は、デフォルトの動作が適用されます。

public class RepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable>  extends JpaRepositoryFactoryBean<R, T, I> {

  protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
    return new MyRepositoryFactory(entityManager);
  }

  private static class MyRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {

    private EntityManager entityManager;

    public MyRepositoryFactory(final EntityManager entityManager) {
      super(entityManager);
      this.entityManager = entityManager;
    }

    protected Object getTargetRepository(final RepositoryMetadata metadata) {
      if (metadata.getDomainType().equals(Bar.class)) {
        return new BarDaoImpl((Class<Bar>) metadata.getDomainType(), entityManager);
      }
      return super.getTargetRepository(metadata);
    }

    protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
      if (metadata.getDomainType().equals(Bar.class)) {
        return BarDao.class;
      }
      return super.getRepositoryBaseClass(metadata);
    }
  }
}

リポジトリクラスとインターフェイス

package com.bar.persistence.dao;

@NoRepositoryBean
public interface BarDao extends JpaRepository<Bar, Long> {
  // no methods - because I want to override save()
}



package com.bar.persistence.dao;

public class BarDaoImpl extends SimpleJpaRepository<Bar, Long> implements BarDao {

  public BarDaoImpl(final Class<Bar> domainClass, final EntityManager em) {
    super(domainClass, em);
  }

  @Override
  public <S extends Bar> S save(final S entity) {
    // some code to perform before actually saving the entity
    entity.setName("intercepted save !");

    // do the save
    return super.save(entity);
  }
}

リポジトリを挿入するテスト

注入するタイプBarDaoのBeanが見つからないため、テストは失敗します。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/persistence-beans.xml")
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@TransactionConfiguration
public class SpringDataLearningTest {

  @Autowired
  private BarDao barDao;

  @Transactional
  @Test
  public void testModifiedSave() throws Exception {
    final Bar original = createRandomBar();
    final Bar saved = barDao.save(original);
    assertNotNull("No id was assigned to the saved entity", saved.getId());
    assertEquals("intercepted save !", saved.getName());
  }

  private static Bar createRandomBar() {...}
}

スプリング構成

<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:task="http://www.springframework.org/schema/task"
       xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:data="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
          http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
          http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

  <!-- Tell Spring Data where to find the interfaces -->
  <data:repositories base-package="com.bar.persistence.dao" factory-class="com.bar.persistence.dao.RepositoryFactoryBean"/>

  <!-- include the definitions of the 'upstream' modules -->
  <import resource="common-beans.xml"/>
  <import resource="io-beans.xml"/>

  <!-- The exception translator service-->
  <bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator"/>

  <bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
  </bean>

  <!-- Use the classic Spring JPA Transaction Manager -->
  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
  </bean>

  <!-- Describes how to connect to the database -->
  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="user" value="${database.user.name}"/>
    <property name="password" value="${database.user.password}"/>
    <property name="driverClass" value="${database.driver}"/>
    <property name="jdbcUrl" value="${database.url}"/>
    <property name="initialPoolSize" value="1"/>
    <property name="maxPoolSize" value="${database.max.pool.size}"/>
    <property name="minPoolSize" value="${database.min.pool.size}"/>
    <property name="acquireIncrement" value="1"/>
    <property name="acquireRetryAttempts" value="3"/>
    <property name="checkoutTimeout" value="10000"/>
  </bean>

  <!-- Describes how to create hibernate sessions -->
  <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
    <property name="persistenceUnitName" value="bars"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaProperties">
      <props>
        <prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
        <prop key="hibernate.cache.use_second_level_cache">${hibernate.second.level.cache}</prop>
        <prop key="hibernate.cache.use_query_cache">${hibernate.query.cache}</prop>
        <prop key="hibernate.generate_statistics">true</prop>
        <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
        <prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
        <prop key="hibernate.show_sql">${database.show.sql}</prop>
        <prop key="hibernate.dialect">${database.hibernate.dialect}</prop>
        <prop key="hibernate.search.default.directory_provider">filesystem</prop>
        <prop key="hibernate.search.default.indexBase">${hibernate.search.dir}</prop>
      </props>
    </property>
  </bean>
</beans>

スタックトレース

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.bar.persistence.dao.SpringDataLearningTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bar.persistence.dao.barDao com.bar.persistence.dao.SpringDataLearningTest.barDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.bar.persistence.dao.BarDao] 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:288)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:379)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:313)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bar.persistence.dao.BarDao com.bar.persistence.dao.SpringDataLearningTest.barDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.bar.persistence.dao.BarDao] 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:514)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    ... 29 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.bar.persistence.dao.BarDao] 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:967)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:837)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:749)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
    ... 31 more
4

1 に答える 1

2

そんな感じ:

  1. @NoRepositoryBeanから削除BarDao
  2. @NoRepositoryBeanBarDaoImplに追加
  3. 移動BarDaoImplBarDaocom.bar.persistence.dao.bar
  4. interface BarDaoMyRepository extends BarDaoに 新規追加com.bar.persistence.dao.repository
  5. セットするbase-package="com.bar.persistence.dao.repository"
  6. 注入するBarDaoMyRepository

拡張するすべてのリポジトリにいくつかの機能を追加する方法を使用していますBarDao(したがって、拡張する必要があり、いくつかの宣言型メソッドを追加する場合があります)。1つのリポジトリにのみ機能を追加する場合は、を参照してください。

http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.introduction1.4.1 単一リポジトリへの動作の追加

于 2013-02-28T22:10:05.423 に答える