Spring 3, Hibernate 4 AutoWired sessionFactory with Generic DAO

13,985

Annotations are not inherited.

Add the transactional annotation to the concrete dao, not the abstract class.

You might like this too

Share:
13,985
Daniel
Author by

Daniel

Software & Web Developer

Updated on June 14, 2022

Comments

  • Daniel
    Daniel about 2 years

    Using Spring MVC 3 & Hibernate 4 I'm getting:

    java.lang.NullPointerException
    
    com.daniel.rr.dao.common.DAOImpl.getSession(DAOImpl.java:22)
    com.daniel.rr.dao.common.DAOImpl.save(DAOImpl.java:27)
    com.daniel.rr.controller.HelloController.printWelcome(HelloController.java:30)
    

    This is the relevant spring configuration:

    <context:annotation-config />
    <tx:annotation-driven transaction-manager="transactionManager" />
    
    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="packagesToScan">
            <list>
                <value>com.daniel.rr.model</value>
                <value>com.daniel.rr.dao</value>
                <value>com.daniel.rr.dao.common</value>
                <value>com.daniel.rr.controller</value>
            </list>
        </property>
    
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    
        <property name="dataSource" ref="dataSource" />
    </bean>
    
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    
        <property name="url" value="jdbc:mysql://localhost:3306/rr" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="username" value="root" />
        <property name="password" value="" />
    
    </bean>
    
    
    
    <bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    

    Generic DAO:

    public interface DAO<T> {
    
        T save(T t);
        void delete(T t);
    } 
    
    @Transactional
    public abstract class DAOImpl<T> implements DAO<T> {
    
        @Autowired
        private SessionFactory sessionFactory;
    
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }
    
        public Session getSession() {
            return sessionFactory.getCurrentSession();
        }
    
        @Override
        public T save(T t) {
            getSession().persist(t);
            return t;
        }
    
        @Override
        public void delete(T t) {
            getSession().delete(t);
        }
    }
    

    AccountDAO:

    public class AccountDAO extends DAOImpl<Account> implements DAO<Account> {
    
    } 
    

    MVC Controller:

    public class HelloController {
    
        @RequestMapping(method = RequestMethod.GET)
        public String printWelcome(ModelMap model) {
    
            //System.out.println("is null? " + sessionFactory);
    
            AccountDAO dao = new AccountDAO();
            Account account = new Account();
    
            account.setUsername("hello");
            account.setPassword("test");
    
            dao.save(account);
    
            model.addAttribute("message", "Hello world!");
            return "hello";
        }
    }
    

    I've searched thru StackOverflow and Google but I cannot find anything that helps. I've tried using a Transaction on DAOImpl.save(T t) but it still has the same issue.

    public T save(T t) {
            Transaction tr = getSession().getTransaction();
            tr.begin();
    
            getSession().persist(t);
    
            tr.commit();
            return t;
        }
    
  • Daniel
    Daniel about 11 years
    Thanks! Found the solution.