Problem with @Autowire Spring + Hibernate and Junit

1

Good night, I'm trying to create a project using Hibernate and Spring, I was successful creating some configurations, I even managed to generate the database by initializing the application using Spring, however I'm "stuck" in creating my DAO's, I use the @Autowired annotation to inject a hibernate sessionFactory created in the spring context in my DaoGeneric class, but when trying to perform tests I get the NullPointerException error when the sessionFactory tries to retrieve a session through the getSession () method, below are some code: p>

Interfaces:

DaoI

     public interface DaoI<T> {

    public void persistir(T objeto);

    public void excluir (T objeto);

    public T get(Integer id);

    public List<T> listar(int de, int ate);

}

DaoUsuarioI

 public interface DaoUsuarioI<T> extends DaoI<T>{

    public void addUsuario(Usuario usuario);

    public void removerUsuario(Usuario usuario);

    public Usuario getUsuario(Integer id);

    public void atualizaUsuario(Usuario usuario);

    public List<Usuario> getUsuarios();

}

Classes:

DaoGeneric

@Transactional(propagation=Propagation.SUPPORTS)
public abstract class DaoGenerico<T> implements DaoI<T> {

    @Autowired
    private SessionFactory sessionFactory;

    private Session getSession(){return getSessionFactory().getCurrentSession();}

    public SessionFactory getSessionFactory() {return sessionFactory;}

    public void setSessionFactory(SessionFactory sessionFactory) {this.sessionFactory = sessionFactory;}

    @SuppressWarnings("rawtypes")
    protected abstract Class getClazz();

    public void persistir(T objeto) {
        getSession().persist(objeto);
    }

    public void excluir(T objeto) {
        getSession().delete(objeto);

    }

    @SuppressWarnings("unchecked")
    public T get(Integer id) {
        return (T) getSession().get(getClazz(), id);

    }

    @SuppressWarnings("unchecked")
    public List<T> listar(int de, int ate) {
        return (List<T>) getSession().createCriteria(getClazz()).setMaxResults(ate).setFirstResult(de).list();

    }

    @SuppressWarnings("unchecked")
    public List<T> listar() {
        return (List<T>) getSession().createCriteria(getClazz()).list();

    }

DaoUser

@Transactional(propagation=Propagation.SUPPORTS)
@Repository("daoUsuario")
public class DaoUsuario extends DaoGenerico<Usuario> implements DaoUsuarioI {


    public void addUsuario(Usuario usuario) {
        persistir(usuario);
    }

    public void removerUsuario(Usuario usuario) {
        removerUsuario(usuario);
    }

    public Usuario getUsuario(Integer id) {
        return get(id);
    }

    public void atualizaUsuario(Usuario usuario) {
        Session s = super.getSessionFactory().getCurrentSession();
        s.update(usuario);
    }

    public List<Usuario> getUsuarios() {
        return listar();
    }

    @SuppressWarnings("rawtypes")
    protected Class getClazz() {
        return Usuario.class;
    }

}

My context is set up in the spring-data.xml file below

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="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/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">


        <context:annotation-config />

        <context:component-scan base-package="br.com.springframework.persistencia" />

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

        <tx:annotation-driven transaction-manager="transactionManager"/>

        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="com.mysql.jdbc.Driver"/>
            <property name="user" value="*******" />
            <property name="password" value="********" />
            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/springframework"/>

            <property name="maxPoolSize" value="30" />
            <property name="acquireIncrement" value="1"/>
            <property name="maxIdleTime" value="120"/>
            <property name="acquireRetryAttempts" value="10"/>
            <property name="initialPoolSize" value="1" />
        </bean> 

        <bean id="sessionFactory" name="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="packagesToScan" value="br.com.springframework.entidades" />
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                    <prop key="hibernate.hbm2ddl.auto">update</prop>
                </props>
            </property>
        </bean>



        <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
</beans>

I'm trying to create tests with JUnit to check the operation of the classes above, but to no avail ... could anyone help?

Thank you ...

    
asked by anonymous 29.12.2014 / 18:37

1 answer

1

Spring has no way to instantiate or inject something into its DaoGeneric class because it is abstract. Your options are:

  • Make your DaoGeneric cease to be abstract and to be the parent of DaoUsuario, to receive the SessionFactory in DaoUsuario (in the constructor, it is much more indicated than to inject directly in the field) and instantiate the DaoGenerico, having an instance in the DaoUsuario . So you can use it where you want, instead of inheriting innumerable methods that most likely DaoUsuario should not have, but have (composition rather than inheritance).

  • Keep the abstract DaoGeneric and parent Daos, get the SessionFactory in DaoUsuario (remembering, via constructor) and you do a super (sessionFactory), and everything works. It's not a bad option, but the way the methods are exposed in the current code makes me prefer the first option.

  • Taking advantage of this, I have other comments on the code:

    • If you only have one implementation of DaoUsuarioI, you do not need the interface, since it is monomorphic. Instantiate the object directly instead of the reference by the interface and remove it.
    • An interface to a generic Dao does not make sense at all. Unless you implement a Dao for Hibernate, one for JPA, and so on.
    30.12.2014 / 00:00