0

I am trying to integrate Spring+Hibernate4, but when I access my DAOs I get a nullPointerException on the sessionFactory object.

This is my AbstractDao:

@Repository
public class AbstractDaoHibernateImpl {



    private SessionFactory sessionFactory;


    public AbstractDaoHibernateImpl() {

    }


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

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }


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

    protected Order getOrder(String orderBy, boolean isOrderAsc) {
        if (isOrderAsc)
            return Order.asc(orderBy);
        else
            return Order.desc(orderBy);
    }
}

This is my entity bean config:

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

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

    <!-- transacciones -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="SessionFactory"/>
    </bean>
    <!--Beans de los servicios de la aplicacion -->
    <bean id="userService" class="com.app.service.user.UserServiceImpl"/>

    <bean name="userDAO" class="com.app.model.user.dao.UserDaoImpl">
        <property name="sessionFactory" ref="SessionFactory" />
    </bean>

    <bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>


</beans>

And this is the rest of my appContext

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:security="http://www.springframework.org/schema/security"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jee="http://www.springframework.org/schema/jee"

        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
            http://www.springframework.org/schema/security
            http://www.springframework.org/schema/security/spring-security-3.1.xsd
            http://www.springframework.org/schema/jee
            http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">

    <context:component-scan base-package="com.app.controllers" />
        <mvc:annotation-driven />
    <context:annotation-config />

<tx:annotation-driven transaction-manager="transactionManager"/>
<import resource="applicationDatasource.xml" />

    <import resource="applicationEntityBean.xml" />


</beans>

And finally this is my Service object:

@Service
public class UsuarioServiceImpl implements IUsuarioService {

    @Autowired
    private IUserDao userDao;

    public List<User> getUsers() throws GenericDataBaseException {
        return userDao.findAll();
    }


}

Shouldn't the sessionFactory object be injected like this?

This is the whole stack trace:

java.lang.NullPointerException
    at es.plexus.core.dao.impl.GenericDaoHibernateImpl.findAll(GenericDaoHibernateImpl.java:243)
    at es.plexus.service.usuario.UsuarioServiceImpl.getUsuarios(UsuarioServiceImpl.java:20)
    at es.plexus.controller.usuario.UsuarioController.listUsuarios(UsuarioController.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:722)

EDIT: userDao:

public class UserDaoImpl extends GenericDaoHibernateImpl<Usuario, Long> implements IUserDao {


}

which extends GenericDao:

public class GenericDaoHibernateImpl<E, PK extends Serializable> extends AbstractDaoHibernateImpl implements GenericDao<E, PK> {

private Class<E> entityClass;
    public GenericDaoHibernateImpl() {
        this.entityClass = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

public List<E> findAll() throws GenericDataBaseException {
        try {
            Criteria criteria = getSession().createCriteria(getEntityClass());

            List<E> result = criteria.list();
            /*
             * if (result == null || result.size() == 0) throw new
             * NoSearchResultException("", getEntityClass().getName());
             */
            return result;
        } catch (Throwable t) {
            Collection<Object> args = new ArrayList<Object>();
            throw exceptionHandler.handle(this, t, "findAll", args);
        }
    }
    (...)
}
MichelReap
  • 5,630
  • 11
  • 37
  • 99

2 Answers2

1

I see no transactions defined anywhere in your code.

In this case I recommend you put them on your service method :

@Transactional(readOnly = true)
public List<User> getUsers() throws GenericDataBaseException {
        return userDao.findAll();
    }

But you seem to be developing a rather complex class hierarchy, all you need is one generic repository and then instantiate that for different types. You don't have to use a service class, they are only recommended when using multiple aggregate roots/complex logic - not a simple getter.

Community
  • 1
  • 1
NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
  • This seems to have properly injected the sessionFactory. I didn't know you had to make every method Transactional. – MichelReap Jun 14 '13 at 08:42
0

Let me take a guess.

Is your DAO under the package com.app.controllers? If not add your dao package to the component scan as in <context:component-scan base-package="com.app.controllers, com.app.model.user.dao" />

Arun Manivannan
  • 4,213
  • 3
  • 29
  • 38
  • Thanks. I am calling the service from a controller, shouldn't that be enough? Anyway I did what you said but I get the same exception... – MichelReap Jun 14 '13 at 08:10
  • My bad. Earlier I just mentioned `com.app.dao`. Corrected the answer to `com.app.model.user.dao`. I guess you did the right thing when you tried. – Arun Manivannan Jun 14 '13 at 08:16
  • Yes, but to no avail either :( – M Rajoy Jun 14 '13 at 08:17
  • And the setters are not mandatory when you are using `@Autowired`. Like you did for the other class, just marking the field as Autowired should do it. – Arun Manivannan Jun 14 '13 at 08:18
  • Can we see your UserDAOImpl (at least the declarative parts) – Arun Manivannan Jun 14 '13 at 08:20
  • I posted it. It actually has no code, it's implemented in a GenericDao – MichelReap Jun 14 '13 at 08:27
  • I am sure you know this - the sessionFactory for some reason is not injected into the DAO. There could only be one reason for this, your DAO is not spring managed. But as you already mentioned, the DAO was added to the component scan. I am sorry, I am unable to think beyond this. – Arun Manivannan Jun 14 '13 at 08:41