Problem with @Autowire Spring + Hibernate and Junit

Asked

Viewed 340 times

1

Good evening, I’m trying to create a project using Hibernate and Spring, I was successful creating some configurations, including I was able to generate the database by booting the application using Spring, but I’m "stuck" in creating my DAO’s, I use the @Autowired annotation to inject a sessionFactory of Hibernate created in the context of spring in my Daogenerico class, but when trying to perform tests I get the Nullpointerexception error when sessionFactory tries to recover a session using the getSession() methodBelow are some codes:

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:

Daogenerico

@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();

    }

Daousuario

@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 configured in the spring-data.xml file, below follows

<?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 am trying to create tests with Junit to verify the functioning of the above classes, but without success... someone could help?

Thank you...

1 answer

1

Spring doesn’t have to instantiate or inject something into its Daogeneric class because it’s abstract. Its options are:

  1. To make his Daogenerico stop being abstract and father of Daousuario, to receive the Sessionfactory in Daousuario (in the builder, it is much more indicated than to inject directly into the field) and to instantiate the Daogenerico, having an instance in Daousuario. So you can use it wherever you want, instead of inheriting countless methods that most likely Daousuario should not have, but has (composition rather than inheritance).

  2. Keep the abstract Daogenerico and father of the other Daos, receive the Sessionfactory in Daousuario (remembering, via constructor) and ae you make a super(sessionFactory), and everything works. Not a bad option, but the way the methods are exposed in the current code makes me prefer the first option.

Taking advantage, I have other comments on the code:

  • if you only have an implementation of Daousuarioi, you don’t need the interface, since it is monomorphic. Install the object directly instead of the reference by the interface and remove it.
  • take 'I' from the names of its interfaces, this is a terrible convention that exists in . net, do not follow it.
  • an interface for a generic Dao makes no sense. Unless you implement a Dao for Hibernate, one for JPA, and so on.
  • Thanks for the reply Juliano, I made some changes following some of your advice and I made "the thing" work here, including in the tests with Junit... I’ve been learning Spring for a few days, but for this case I think I lack concept related to the use of Generics to build something more elaborate and that works. I managed to make it work by creating the persistence layer in a more "archaic" way, you have some link/material that can help me better understand how to use Generics to apply in an interesting way on my persistence layer?

  • I don’t think so. I don’t remember any material about Generics used in this specific way. But about Daogenerico you find without difficulties :)

  • Opa Juliano, I managed to implement the code posted, Spring manages to perform injection in abstract classes, I was wrong at the time of instantiating the classes created above... the right would be through the interface representing the same.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.