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?