biriba
biriba

Reputation: 69

SessionFactory Hibernate Error (Spring MVC project)

This is the error: Caused by:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of 
type [org.hibernate.SessionFactory] 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)}

This is my persistence-context.xml:

<?xml version="1.0" encoding="UTF-8"?>

<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"
    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">

    <!-- Datasource to connection management (http://commons.apache.org/dbcp/configuration.html)
     -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${datasource.mysql.driverClassName}" />
        <property name="jdbcUrl" value="${datasource.mysql.url}" />
        <property name="user" value="${datasource.mysql.username}" />
        <property name="password" value="${datasource.mysql.password}" />
        <property name="maxIdleTime" value="${datasource.mysql.maxIdle}" />
    </bean>

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="br.com.mirian.martins.core.model" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
                <prop key="hibernate.c3p0.timeout">${datasource.mysql.timeout}</prop>
                <prop key="hibernate.connection.release_mode">after_transaction</prop>
            </props>
        </property>
    </bean>

    <!-- Transaction manager for a single Hibernate SessionFactory -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager"
        scope="prototype">
        <property name="sessionFactory" ref="sessionFactory" />
        <property name="defaultTimeout" value="120" />
    </bean>

    <bean id="transactionTemplate"
        class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager" />
    </bean>
</beans>

This is my DAOImpl (generic):

/**
 * Classe generica com metodos padroes utilizados na camada de persistencia
 * 
 * @param <T>
 * @param <ID>
 */
public class DAOImpl<T, ID extends Serializable>{

    private transient final Class<T> clazz;

    @Autowired
    private SessionFactory sessionFactory;

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

    /**
     * SessionFactory injection
     * 
     * @param sessionFactory
     */
    public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
    }

    /**
     * Recupera a sessao corrente
     * 
     * @return sessao corrente
     */
    protected Session getSession() {
    return sessionFactory.getCurrentSession();
    }

    /**
     * Utiliza a sessao corrente para criar uma nova instancia de criteria
     * 
     * @return instancia de criteria
     */
    protected Criteria createCriteria() {
    return getSession().createCriteria(clazz);
    }

    /**
     * Utiliza a sessao corrente para criar uma nova query
     * 
     * @param hql
     * @return query
     */
    protected Query createQuery(String hql) {
    return getSession().createQuery(hql);
    }
}

This is my controller:

@Controller
public class IndexController {

    @Autowired
    UserService userService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(HttpServletRequest request, HttpServletResponse response) {


    return "index";

    }

}

Please, if someone now how to solve this problem. Thanks

Upvotes: 1

Views: 1260

Answers (3)

Ashish Jagtap
Ashish Jagtap

Reputation: 2819

Here you are getting confused in two things

  1. JPA EntityManagerFactory

    EntityManagerFactory and EntityManager. They are defined by the JPA standard.

  2. SessionFactory

    SessionFactory and Session are hibernate-specific.

both have there Pros & Cons, since you use SessionFactory (not JPA), you shouldn't use persistence.xml at all.

JPA EntityManagerFactory

If you want to use JPA with Spring, you need to put persistence.xml into META-INF folder inside your source folder, and declare LocalContainerEntityManagerFactory in applicationContext.xml

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name = "persistenceUnitName" value = "MyJPA" />
</bean>

Then you can inject EntityManager into your Spring bean using @PersistenceContext:

@PersistenceContext
private EntityManager em;

persistence.xml

this files usually contain details related to your database, such as connection strings and their respective user names and passwords including other ORM related information. These details can be placed in other locations so you need not explicitly have one, although having such a file usually makes all persistence related information available in one place which makes looking up certain settings and configurations easier.

SessionFactory

If you want to use SessionFactory then you have to declare sessionFactory bean into your applicationContext.xml as follows

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${datasource.mysql.driverClassName}" />
        <property name="jdbcUrl" value="${datasource.mysql.url}" />
        <property name="user" value="${datasource.mysql.username}" />
        <property name="password" value="${datasource.mysql.password}" />
        <property name="maxIdleTime" value="${datasource.mysql.maxIdle}" />
    </bean>

     <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="com.edgeowt.entities"/>
        <property name="hibernateProperties">
            <props>
                <prop key="show_sql">${hibernate.show_sql}</prop>
                  <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

Then you can able to inject SessionFactory into your spring bean using @Autowired

@Autowired
private SessionFactory sessionFactory;

hope this will help you to solve your problem...

Upvotes: 3

Phong Nguyen
Phong Nguyen

Reputation: 277

You must add @Repository (Spring annotation) at the top of your DAOImpl class. Moreover, you must insert <context:component-scan base-package="packageName"/> to scan all your project and find mvn components in your project and <mvc:annotation-driven /> (to enable to use spring annotation) in spring configuration, so that it can understand your spring annotation.

Upvotes: 1

user3120173
user3120173

Reputation: 1788

You need to add @Component at the top of your DAO (or a similar Spring annotation). Also do you have <context:annotation-config/> and <context:component-scan base-package="whatever"/> in your web.xml? You have to tell Spring to go out and sniff around for annotations.

Upvotes: 1

Related Questions