2016-03-15 4 views
2

У меня есть фасоль в упаковке - data.daoне @Autowired Нет квалификационная рожкового типа - Bean расширения Абстрактный класс

@Component("questionDao") 
@Transactional 
public class QuestionDao extends AbstractDao<Question, Long>{ 

} 

(все методы реализованы в AbstractDao) Я пишу TestClass для этого боба и I используйте autowiring следующим образом:

@Autowired 
@Qualifier(value="questionDao") 
private QuestionDao questionDao; 

Таким образом, он работает без проблем!

Теперь мне нужно добавить очень специфический метод QuestionDao фасоли, поэтому я изменить его немного:

@Component("questionDao") 
@Transactional 
public class QuestionDao extends AbstractDao<Question, Long>{ 
    public void doSomething(){ 
    } 
} 

Как только я изменить мой боб (тело не является пустым) автоматического связывания не работает для некоторых причина ... "Нет готового компонента типа data.dao.QuestionDao, найденного для зависимости. (Я использую Spring 4.x) Любые идеи, что может пойти не так (в сценарии 1 он работает как шарм, но как только я касаюсь QuestionDao класс не автоподключен)

Это мой раздел AbstractDao

public class AbstractDao<T, ID extends Serializable> implements Dao<T, ID> { 

    @Autowired 
    protected SessionFactory sessionFactory; 

    private Class<T> persistentClass; 
    private Transaction transaction; 

    @SuppressWarnings("unchecked") 
    public AbstractDao() { 
     this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()) 
       .getActualTypeArguments()[0]; 
    } 

    protected Session getSession() { 
     return sessionFactory.getCurrentSession(); 
    } 

    public Class<T> getPersistentClass() { 
     return persistentClass; 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    public T findById(ID id) { 
     transaction = getSession().beginTransaction(); 

     T object = (T) getSession().load(this.getPersistentClass(), id); 

     transaction.commit(); 

     return object; 
    } 

    @Override 
    public List<T> findAll() { 
     transaction = getSession().beginTransaction(); 

     List<T> list = this.findByCriteria(); 

     transaction.commit(); 

     return list; 
    } 

    @SuppressWarnings("unchecked") 
    protected List<T> findByCriteria(Criterion... criterion) { 
     Criteria crit = this.getSession().createCriteria(this.getPersistentClass()); 

     for (Criterion c : criterion) { 
      crit.add(c); 
     } 
     return (List<T>) crit.list(); 
    } 

    @Override 
    public T create(T entity) { 
     transaction = getSession().beginTransaction(); 

     getSession().saveOrUpdate(entity); 

     transaction.commit(); 

     return entity; 
    } 

    @Override 
    public void delete(T entity) { 
     transaction = getSession().beginTransaction(); 

     getSession().delete(entity); 

     transaction.commit(); 
    } 

    @Override 
    public void deleteTable() { 
     transaction = getSession().beginTransaction(); 

     String deleteTable = new String ("delete " + this.getPersistentClass().getName()); 

     Query query = getSession().createQuery(deleteTable); 
     query.executeUpdate(); 

     transaction.commit(); 
    } 

} 

Вот конфигурация для SessionFactory

<bean id="sessionFactory" 
      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
      <property name="dataSource" ref="dataSource"></property> 
      <property name="hibernateProperties"> 
       <props> 
        <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</prop> 
        <prop key="hibernate.show_sql">true</prop> 
       </props> 
      </property> 
      <property name="packagesToScan"> 
       <list> 
        <value>sk.uniza.fri.cuka.data.dao</value> 
        <value>sk.uniza.fri.cuka.data.entity</value> 
       </list> 
      </property> 
     </bean> 

Полный StackTrace:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sk.uniza.fri.cuka.test.tests.AnswerDaoTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private sk.uniza.fri.cuka.data.dao.QuestionDao sk.uniza.fri.cuka.test.tests.AnswerDaoTest.questionDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [sk.uniza.fri.cuka.data.dao.QuestionDao] 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), @org.springframework.beans.factory.annotation.Qualifier(value=questionDao)} 
    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.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:385) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) 
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private sk.uniza.fri.cuka.data.dao.QuestionDao sk.uniza.fri.cuka.test.tests.AnswerDaoTest.questionDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [sk.uniza.fri.cuka.data.dao.QuestionDao] 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), @org.springframework.beans.factory.annotation.Qualifier(value=questionDao)} 
    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) 
    ... 26 more 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [sk.uniza.fri.cuka.data.dao.QuestionDao] 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), @org.springframework.beans.factory.annotation.Qualifier(value=questionDao)} 
    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) 
    ... 28 more 

редактировать: Проблема решена: Я только что удалили "@Transactional", и это работает. Я также реорганизую немного своего QuestionDao, поэтому он реализует интерфейс, как предложил Питер Юркович.

ответ

2

Существует проблема с интерфейсом Dao. Извлеките интерфейс из QuestionDao, и он должен работать.

public interface QuestionDao extends Dao<Question, Long>{ 
    public void doSomething(); 
} 

Создать QuestionDaoImpl

@Transactional 
@Repository("questionDao") 
public class QuestionDaoImpl extends AbstractDao<Question, Long> implements QuestionDao{ 
    public void doSomething(){ 
    } 
} 
+0

Сначала у меня это было, но я получаю ту же ошибку. Я просто попробовал это снова, как вы показываете, но я получаю по-прежнему ту же ошибку, damn :( –

+0

Какой режим прокси-сервера AOP вы используете? По компоненту аннотации с '@ Transactional' будет создан прокси для данного компонента. Я также не понимаю, почему вы использовали @Transactional при управлении транзакциями в вашем коде. Профилирует ли компонент QuestionDao при запуске приложения? –

+1

Ну, я использую Spring 4.1.7, и я использую режим прокси-сервера AOP по умолчанию (i я новичок в Spring, я вообще не трогал его) .Когда я удаляю @Transactional, он работает. Большое спасибо. Думаю, мне нужно кое-что прочитать об этой аннотации, не уверен, почему я ее использовал и почему это вызывало проблемы ... –

0

Hum, теперь с вашим редактированием, мне интересно, может ли это быть из-за @Autowired protected SessionFactory sessionFactory; внутри вашего абстрактного метода, который нельзя автоувеличивать. У вас есть дополнительная информация в вашем стеке? Я бы постарался заменить его установщиком или конструктором @Autowired.

что-то вроде этого:

public class AbstractDao<T, ID extends Serializable> implements Dao<T, ID> { 

    protected SessionFactory sessionFactory; 

    @Autowired 
    public AbstractDao(SessionFactory sessionFactory){ 
     this.sessionFactory= sessionFactory; 
    } 

/// 
} 

Тогда вам нужно создать конструктор в вашем QuestionDao слишком

---- не фиксируя проблему.

Попробуйте это:

@Component 
@Transactional 
@Qualifier("questionDao") 
public class QuestionDao extends AbstractDao<Question, Long>{ 
    public void doSomething(){ 
    } 
} 
+0

все та же ошибка –

+0

Hum, теперь ваши изменения, я интересно, возможно ли это из-за '' '@Autowired protected SessionFactory sessionFactory;' '' внутри вашего абстрактного метода, который нельзя автоувеличивать.У вас есть дополнительная информация в вашем стеке? Можете ли вы попробовать заменить его установщиком или конструктором '' '@ Autowired'''? – maximede

+0

Это абстрактный класс, поэтому мне нужно использовать setter, но он все еще не работает для меня. Я не уверен, как мне изменить свой QuestionDao (конструктор, о котором вы упоминали) –

0

это исключение создается путем сканирования пакетов в компонентах и ​​добавьте XML-файл configration <jpa:repositories base-package="sk.uniza.fri.cuka.data.dao"/>

Смежные вопросы

 Смежные вопросы