No qualifying bean of type 'my class' available Spring
Не понимаю почему возникает ошибка. Если в класс PersonDAOHibernate добавляю конструкторы (по умолчанию или с параметром SessionFactory), то они вызываются т.е. бин создаётся.
В стуктуре проекта видно, что Idea подсвечивает главный класс серым, но к чему это она - непонятно.
ApplicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:th="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
>
<context:property-placeholder location="jdbc.properties"/>
<context:component-scan base-package="org.example.dao"/>
<th:annotation-driven/>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<util:properties id="hibernateProperties">
<prop key="hibernateDialect">org.hibernate.dialect.PostgreSQL10Dialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">false</prop>
</util:properties>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
p:dataSource-ref="dataSource"
p:packagesToScan="org.example.dao"
p:hibernateProperties-ref="hibernateProperties"/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
</beans>
Класс PersonDAOHibernate:
package org.example.dao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* * @author Andrey Fyodorov
*/
@Transactional
@Repository("personDao")
public class PersonDAOHibernate implements PersonDAO {
private static final Log LOG = LogFactory.getLog(PersonDAOHibernate.class);
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Resource(name="sessionFactory")
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
@Transactional(readOnly=true)
public List<Person> index() {
//language=HQL
return getSessionFactory().getCurrentSession().createQuery("from Person c").list();
}
@Override
@Transactional(readOnly=true)
public Person show(int id) {
return getSessionFactory().getCurrentSession().byId(Person.class).load(id);
}
@Override
public void update(@NotNull Person person) {
getSessionFactory().getCurrentSession().update(person);
LOG.info("Person saved with id: "+ person.getId());
}
@Override
public void delete(int id) {
getSessionFactory().getCurrentSession().delete(id);
LOG.info("Person deleted with id: "+ id);
}
@Override
public void create(@NotNull Person person) {
getSessionFactory().getCurrentSession().save(person);
}
}
Класс Person:
package org.example.dao;
import javax.persistence.*;
import static javax.persistence.GenerationType.IDENTITY;
/**
* * @author Andrey Fyodorov
*/
@Entity
@Table(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "age")
private int age;
@Column(name = "email")
private String email;
public int getId() {
return id;
}
public Person() {
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getEmail() {
return email;
}
public void print() {
System.out.printf("%d %s %d %s",id, name, age, email);
}
}
Класс Application:
package org.example;
import org.example.dao.Person;
import org.example.dao.PersonDAOHibernate;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* * @author Andrey Fyodorov
*/
public class Application {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
PersonDAOHibernate daoHibernate = applicationContext.getBean(PersonDAOHibernate.class);
Person kira = daoHibernate.show(3);
kira.print();
applicationContext.close();
}
}
Сама ошибка:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.example.dao.PersonDAOHibernate' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1127)
at org.example.Application.main(Application.java:14)
Интрерфейс PersonDAO скидывать не стал, там просто 5 методов, которые я реализую в PersonDAOHibernate.
Ответы (1 шт):
Ответ получен эмпирическим методом. Буду очень благодарен, если кто-то объяснит почему это работает.
Решение: в 14 строке Application передавать имя интерфейса, а не класса.
PersonDAO daoHibernate = applicationContext.getBean(PersonDAO.class);
UPD
Так же всё работает, если в PersonDAOHibernate не реализовывать интерфейс PersonDAO (мейн менять не нужно).
