I just tried to switch to continuations and received an error because of the method I am using to access my business objects. Essentially what I am doing is as follows:
OrderActions.java - the action object (extends FormAction) for the Web Flow which contains setters to receive business object managers, and then places the reference to these managers into the flow scope
Country.java - a (serializable) business object that would contain a single country
CountryManager.java - a business object manager which retrieves lists of Country(s), can insert a Country, delete a Country, and update a Country using a DAO
CountryManagerDao.java - an (interface) definition for what a CountryManagerDao implementation is allowed to do
CountryManagerSqlMap.java - an implementation of CountryManagerDao for iBatis SQL Maps
Three beans are then created:
orderActions - a bean for OrderActions.java for use in the Web Flow which is passed a reference to countryMan (which is then placed into the flow scope)
countryMan - a bean for CountryManager.java which is passed a reference to countryManDao
countryManDao - a bean for CountryManagerDaoSqlMap.java
This allowed me (prior to using Continuations) to retrieve a list of countries to populate form fields from within my .jsp view using the flow scoped countryMan (placed there by orderActions). However, since only Country.java is Serializable, I get the following error:
Tomcat 5.5.17 with JRE 1.5.0_07, SWF 1.0 RC3, and Spring 2.0 RC2
This is obviously expected, but it raises the question on how is one supposed to get a list of countries if I don't want to make my DAO objects and managers Serializable? Should I be using a different design to store/access my data? I don't want the view to have too much control over the objects, but I also don't want to generate too much code. I used to use ASP.NET with C# and I could simply call the class as a static class (you can access static methods directly if you don't use an instance) in the following way, assuming I have a Country object:Code:org.springframework.webflow.execution.repository.continuation.ContinuationCreationException: Could not serialize flow execution; make sure all objects stored in flow scope are serializable; nested exception is java.io.NotSerializableException: com.company.db.PaymentMethodTypeManagerDaoSqlMap org.springframework.webflow.execution.repository.continuation.SerializedFlowExecutionContinuationFactory.createContinuation(SerializedFlowExecutionContinuationFactory.java:71) org.springframework.webflow.execution.repository.continuation.ContinuationFlowExecutionRepository.putFlowExecution(ContinuationFlowExecutionRepository.java:188) org.springframework.webflow.execution.repository.support.RebindingFlowExecutionRepository.putFlowExecution(RebindingFlowExecutionRepository.java:69) org.springframework.webflow.executor.FlowExecutorImpl.launch(FlowExecutorImpl.java:211) org.springframework.webflow.executor.support.FlowRequestHandler.handleFlowRequest(FlowRequestHandler.java:129) org.springframework.webflow.executor.mvc.FlowController.handleRequestInternal(FlowController.java:199) org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:45) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:800) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:730) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:396) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:350) javax.servlet.http.HttpServlet.service(HttpServlet.java:689) javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
ASP.NET C# Example
This does not create an instance of Country, rather it accesses the static getAllCountries() method in the Country class directly, which then returns an ArrayList. This seems like a much cleaner method than having to create a second layer and then inject that into the form controller for IoC. I really want to understand how to do this cleanly in IoC, and would love to hear any suggestions or corrections. I'm having trouble wrapping my head around this.Code:ArrayList alCountries = Country.getAllCountries();
Below is the code I am using for all objects referred to above:
orderActions bean
countryMan beanCode:<bean id="orderActions" class="com.company.web.OrderActions"> <property name="countryMan" ref="countryMan"/> <property name="orderformMan" ref="orderformMan"/> <property name="paymentMethodTypeMan" ref="paymentMethodTypeMan"/> <property name="stateMan" ref="stateMan"/> <property name="userMan" ref="userMan"/> <property name="validator"> <bean class="com.company.web.OrderValidator"> <property name="userMan" ref="userMan"/> </bean> </property> </bean>
countryManDao beanCode:<bean id="countryMan" class="com.company.bus.entity.CountryManager"> <property name="countryManagerDao" ref="countryManDao"/> </bean>
com.company.bus.entity.Country.java (Serializable)Code:<bean id="countryManDao" class="com.company.db.CountryManagerDaoSqlMap"> <property name="dataSource" ref="dataSource"/> <property name="sqlMapClient" ref="sqlMapClient"/> </bean>
com.company.bus.entity.CountryManagerCode:package com.company.bus.entity; import java.io.Serializable; import java.lang.Short; import java.lang.String; public class Country implements Serializable { private Short id; private String name; public Country () { this(null,""); } public Country (Short id, String name) { this.id = id; this.name = name; } //private Short id; public void setId (Short id) { this.id = id; } public Short getId () { return id; } //private String name; public void setName (String name) { this.name = name; } public String getName () { return name; } }
com.company.db.CountryManagerDao.java (interface)Code:package com.company.bus.entity; import java.lang.Short; import java.util.List; import com.company.bus.entity.Country; import com.company.db.CountryManagerDao; public class CountryManager { private CountryManagerDao dao; public void setCountryManagerDao (CountryManagerDao dao) { this.dao = dao; } public List<Country> getCountries () { return dao.getCountries(); } public Country getCountryById (Short id) { return dao.getCountryById(id); } public void insertCountry (Country country) { dao.insertCountry(country); } public void updateCountry (Country country) { dao.updateCountry(country); } }
com.company.db.CountryManagerDaoSqlMap.java (CountryManagerDao.java implementation)Code:package com.company.db; import java.lang.Short; import java.util.List; import com.company.bus.entity.Country; public interface CountryManagerDao { public List<Country> getCountries (); public Country getCountryById (Short id); public void insertCountry (Country country); public void updateCountry (Country country); }
Code:package com.company.db; import java.lang.Short; import java.util.List; import org.springframework.dao.DataAccessException; import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport; import com.company.bus.entity.Country; public class CountryManagerDaoSqlMap extends SqlMapClientDaoSupport implements CountryManagerDao { private Country country; public List<Country> getCountries () { return getSqlMapClientTemplate().queryForList("getCountries",null); } public Country getCountryById (Short id) { country = new Country(); country.setId(id); country = (Country)getSqlMapClientTemplate().queryForObject("getCountryById",country); return country; } public void insertCountry (Country country) { getSqlMapClientTemplate().insert("insertCountry",country); } public void updateCountry (Country country) { getSqlMapClientTemplate().update("updateCountry",country); } }


Reply With Quote