I have a bean in package - data.dao
@Component("questionDao")
@Transactional
public class QuestionDao extends AbstractDao<Question, Long>{
}
(all methods are implemented in AbstractDao) I am writing testClass for this bean and I use autowiring like this:
@Autowired
@Qualifier(value="questionDao")
private QuestionDao questionDao;
This way it works without any problem!
Now I need to add very specific method for QuestionDao bean so I've change it a little bit:
@Component("questionDao")
@Transactional
public class QuestionDao extends AbstractDao<Question, Long>{
public void doSomething(){
}
}
As soon as I modify my bean (body is not empty) Autowiring doesnt work for some reason... "No qualifying bean of type data.dao.QuestionDao found for dependency. (I am using Spring 4.x) Any ideas what can go wrong (In scenario 1 it works like charm but as soon as I touch QuestionDao class it fails to autowire)
Here's my AbstractDao class
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();
}
}
Here's configuration for 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>
Full 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
edit: Problem solved: I just removed "@Transactional" and it works. I also refactor a little bit my QuestionDao so it implements interface as suggested Peter Jurkovic.
There is a issue with Dao interface. Extract interface form your QuestionDao
and it should works.
public interface QuestionDao extends Dao<Question, Long>{
public void doSomething();
}
Create QuestionDaoImpl
@Transactional
@Repository("questionDao")
public class QuestionDaoImpl extends AbstractDao<Question, Long> implements QuestionDao{
public void doSomething(){
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With