0


We are working on a Tapestry5-Spring-Hibernate application.
We are using Tapestry 5.4.1, Spring 4.3.1.RELEASE and Hibernate 4.3.6.Final.
We are using and XML based application.
We are facing the problem that all daos @Autowired into spring services are always null. This will of course generate a NullpointerException everytime a dao is needed to perform an operation on the database.
We used generic service and dao interfaces
Here are the code samples:
Spring config file

<context:annotation-config />
    <context:component-scan base-package="org.prism.forecast" />

    <context:property-placeholder location="classpath:hibernate.properties" />
 <!--Generic DAO -->
    <bean id="appDao" primary="true" class="org.prism.forecast.dao.AppDaoImpl">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>
    <!--Generic service-->
    <bean id="appServiceImpl" class="org.prism.forecast.services.AppServiceImpl">
        <property name="dao">
            <ref bean="appDao" />
        </property>
    </bean>

    <bean id="requestDao" class="org.prism.forecast.dao.RequestDaoImpl">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>

    <bean id="requestServiceImpl" class="org.prism.forecast.services.RequestServiceImpl">
        <property name="dao">
            <ref bean="requestDao" />
        </property>
    </bean>

     <bean id="SOPUploadDao" class="org.prism.forecast.dao.SOPUploadDaoImpl">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>

    <bean id="SOPUploadServiceImpl" class="org.prism.forecast.services.SOPUploadServiceImpl">
        <property name="dao">
            <ref bean="SOPUploadDao" />
        </property>
    </bean>

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

   <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
      <property name="driverClassName" value="${jdbc.driverClassName}" />
      <property name="url" value="${jdbc.url}" />
      <property name="username" value="${jdbc.username}" />
      <property name="password" value="${jdbc.password}" />
   </bean>

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

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

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

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


Generic DAO Interface

public interface AppDao {

    /**
     * Finds an object by id
     * 
     * @param <T>
     * @param <PK>
     * @param type
     * @param id
     * @return the object
     */
    <T, PK extends Serializable> T find(Class<T> type, PK id);
//other methods
}

Generic DAO implementation

@Repository("appDao")
public class AppDaoImpl implements AppDao {

    protected static final Logger logger = LoggerFactory.getLogger(RequestDaoImpl.class);

    @Inject
    protected Session session;

    @Resource(name = "sessionFactory")
    protected SessionFactory sessionFactory;


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

    @SuppressWarnings("unchecked")
    public <T, PK extends Serializable> T find(Class<T> type, PK id) {
        return (T) session.get(type, id);
    }
//other methods
}

Request DAO

public interface RequestDao extends AppDao {
}

Request DAO Implementation

@Repository("requestDao")
public class RequestDaoImpl extends AppDaoImpl implements RequestDao {
}

Generic service

public interface AppService {

    /**
     * @param <T>
     * @param <PK>
     * @param type
     * @param id
     * @return the object
     */
    <T, PK extends Serializable> T find(Class<T> type, PK id);
//Other methods
}

Generic service implementation

@Service("appService")
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public class AppServiceImpl implements AppService {

    @Autowired
    private AppDao dao = null;

    /**
     * @return the dao
     */
    public AppDao getDao() {
        return dao;
    }

    /**
     * @param dao
     *            the dao to set
     */
    public void setDao(AppDao dao) {
        this.dao = dao;
    }

    @Override
    public <T, PK extends Serializable> T find(Class<T> type, PK id) {
        return dao.find(type, id);//dao is null here
    }
//other methods
}

Request Service

public interface RequestService extends AppService {
}

Request Service Implementation

@Service("requestService")
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public class RequestServiceImpl extends AppServiceImpl implements RequestService {

    @Autowired
    private RequestDao dao;

    @Override
    public Request find(Request request) {
        dao.find(request);
    }
//other methods
}

Usage in Tapestry pages

public class ManageRequest{

    //dao needed for persistence operations
    @InjectService("requestService")
    protected requestService service;
}

While debugging the application we figured out that the service has been properly injected into the page but the dao has not been injected into the service. Can anybody tell me what is going wrong here?

Arthur bauer
  • 633
  • 7
  • 11

1 Answers1

0

This looks like Spring configuration issue, could it be that you need to specify sub package of your DAO services explicitly in <context:component-scan ... />, i.e.:

<context:component-scan base-package="org.prism.forecast, org.prism.forecast.dao" />

Some hints: @Autowired service is null, and multiple packages in context:component-scan.

Dmitry Gusev
  • 881
  • 8
  • 15