I'm having trouble setting up Spring with Hibernate under GWT framework. I am fairly new to GWT. I have the application context set up and loading without output errors, but my main issue at the moment is that the my Service layer implementation (PobaseServiceImpl) requires a DAO that I set up in the appcontext but its not wrapping the DAO. Naturally my RPC is attempting to call the dao methods resulting in a NullPointerException. The pobaseDao is not being set by the TransactionProxyFactoryBean when I initialize it.
In summary: The DAO should be created by (that is, configured into) Spring just like the rest of my services. Then injected to the services via Spring. Then with the DAO, wrap it in a Spring transaction proxy (org.springframework.transaction.interceptor.TransactionProxyFactoryBean) and give it a Hibernate SessionFactory (org.springframework.orm.hibernate4.LocalSessionFactoryBean). But for some reason its not setting the dao
So my application context is being loaded through a ServletContextListener. Here is my application context:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
Spring Framework application context definition for the POBASE Website.
-->
<beans>
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/pobase.properties</value>
<value>file:${user.home}/pobase.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="no"/>
</bean>
<!-- Hibernate Data Source -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${pobase.database.driver}" />
<property name="url" value="${pobase.database.url}" />
<property name="username" value="${pobase.database.user}" />
<property name="password" value="${pobase.database.password}" />
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="packagesToScan" value="nz.co.doltech.pobase.client.entity"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${pobase.hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${pobase.hibernate.show_sql}</prop>
<prop key="javax.persistence.validation.mode">none</prop>
</props>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Default transaction proxy, defining the transactional behaviour for
a typical Dao configuration -->
<bean id="baseDaoTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<value>*=PROPAGATION_MANDATORY</value>
</property>
</bean>
<!-- Default transaction proxy, defining the transactional behaviour for
a typical Service configuration -->
<bean id="baseServiceTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<value>*=PROPAGATION_REQUIRED</value>
</property>
</bean>
<!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->
<bean id="pobaseDao" parent="baseDaoTransactionProxy">
<property name="target" ref="pobaseDaoTarget" />
</bean>
<bean id="pobaseDaoTarget" class="nz.co.doltech.pobase.server.dao.PobaseHibernateDao">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="pobaseService" parent="baseServiceTransactionProxy">
<property name="target" ref="pobaseServiceTarget" />
</bean>
<bean id="pobaseServiceTarget" class="nz.co.doltech.pobase.server.service.PobaseServiceImpl">
<property name="pobaseDao" ref="pobaseDao" />
<!-- property name="accessControlService" ref="accessControlService" />
<property name="lookupService" ref="lookupService"/>
<property name="notificationService" ref="notificationService"/ -->
</bean>
</beans>
and here is my RPC servlet implementation:
package nz.co.doltech.pobase.server.service;
/**
* Extends RSS and implements the PobaseService
* @author Ben
*/
@SuppressWarnings("serial")
public class PobaseServiceImpl extends RemoteServiceServlet implements PobaseService {
@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(PobaseServiceImpl.class.getName());
private PobaseDao pobaseDao;
private final HashMap<Integer, PobaseEntity> pobaseEntities = new HashMap<Integer, PobaseEntity>();
private void fetchExternPobase()
{
pobaseEntities.clear();
List<PobaseEntity> pobaseList = pobaseDao.getAllPobase();
for (int i = 0; i < pobaseList.size(); i++)
{
PobaseEntity en = pobaseList.get(i);
if(en != null) {
pobaseEntities.put(en.getId(), en);
}
}
}
public void setPobaseDao(PobaseDao dao)
{
this.pobaseDao = dao;
}
public PobaseDao getPobaseDao()
{
return this.pobaseDao;
}
public PobaseData addLocalPobase(PobaseData pobase)
{
PobaseEntity entity = new PobaseEntity();
entity.mirrorObjectData(pobase);
pobase.setId(pobaseEntities.size());
pobaseEntities.put(pobase.getId(), entity);
return entity.getDataObject();
}
public PobaseData updateLocalPobase(PobaseData pobase)
{
PobaseEntity entity = new PobaseEntity();
entity.mirrorObjectData(pobase);
pobaseEntities.remove(entity.getId());
pobaseEntities.put(entity.getId(), entity);
return entity.getDataObject();
}
public Boolean deleteLocalPobase(int id)
{
pobaseEntities.remove(id);
return true;
}
public ArrayList<PobaseData> deleteLocalPobases(ArrayList<Integer> ids)
{
for (int i = 0; i < ids.size(); ++i) {
deleteLocalPobase(ids.get(i));
}
return getLocalPobaseData();
}
public ArrayList<PobaseData> getLocalPobaseData()
{
ArrayList<PobaseData> pobaseList = new ArrayList<PobaseData>();
Iterator<Integer> it = pobaseEntities.keySet().iterator();
while(it.hasNext())
{
PobaseData pobase = pobaseEntities.get(it.next()).getDataObject();
pobaseList.add(pobase);
}
return pobaseList;
}
public PobaseData getLocalPobase(int id)
{
return pobaseEntities.get(id).getDataObject();
}
public ArrayList<PobaseData> resyncExternPobase()
{
fetchExternPobase();
return getLocalPobaseData();
}
}
Also here is the start-up log for the web application:
ServletContextListener started
Nov 12, 2012 8:20:33 PM nz.co.doltech.pobase.SpringInitialiser initSpringContext
INFO: Creating new Spring context. Configs are [/nz/co/doltech/pobase/appcontext.xml]
Nov 12, 2012 8:20:33 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@8423321: startup date [Mon Nov 12 20:20:33 NZDT 2012]; root of context hierarchy
Nov 12, 2012 8:20:33 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [nz/co/doltech/pobase/appcontext.xml]
Nov 12, 2012 8:20:33 PM org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from class path resource [pobase.properties]
Nov 12, 2012 8:20:33 PM org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from URL [file:/home/ben/pobase.properties]
Nov 12, 2012 8:20:33 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@4c56666d: defining beans [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,dataSource,sessionFactory,transactionManager,baseDaoTransactionProxy,baseServiceTransactionProxy,pobaseDao,pobaseDaoTarget,pobaseService,pobaseServiceTarget]; root of factory hierarchy
Nov 12, 2012 8:20:33 PM org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName
INFO: Loaded JDBC driver: org.postgresql.Driver
Nov 12, 2012 8:20:33 PM org.hibernate.annotations.common.Version <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
Nov 12, 2012 8:20:33 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.1.7.Final}
Nov 12, 2012 8:20:33 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Nov 12, 2012 8:20:33 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Nov 12, 2012 8:20:34 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
Nov 12, 2012 8:20:34 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
Nov 12, 2012 8:20:34 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
Nov 12, 2012 8:20:34 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Nov 12, 2012 8:20:34 PM org.springframework.orm.hibernate4.HibernateTransactionManager afterPropertiesSet
INFO: Using DataSource [org.springframework.jdbc.datasource.DriverManagerDataSource@55acc0d4] of Hibernate SessionFactory for HibernateTransactionManager
Starting Jetty on port 8888
Anyone have any ideas as to why its not working? Some specs here:
- Spring 3.2.0
- Hibernate4
- GWT SDK 2.4.0
Appreciate any help I can get!
Cheers, Ben