问题
I am into a problem from two days and I can not get out from this.
The problem I am having is using a MangedBean property after the deserialization (I guess).
The property (purchaseManager) is set up with Spring, and use a DAO which extends MyBatis as data mapper to interact with the DB.
In fact, on the first access to the page, purchaseManager.getAll() inside init() method works fine.
When i try to call refreshList() as an action from a button, I have a NullPointerException on the getSqlSession() inside the DAO.
Letting only the relevant code the situation is as follow:
@ManagedBean(name = "purchaseController")
@ViewScoped
public class PurchaseController implements Serializable{
@ManagedProperty(value = "#{purchaseManager}")
private PurchaseManager purchaseManager;
@PostConstruct
public void init(){
purchaseManager.getAll();
}
public void refreshList(){
purchaseManager.getAll();
}
}
public class PurchaseManagerImpl implements PurchaseManager, Serializable {
PurchaseDAO purchaseDAO;
public void getAll() {
purchaseDAO.getAll()
}
}
public class PurchaseDAOImpl extends SqlSessionDaoSupport implements PurchaseDAO, Serializable {
public void getAll() {
SqlSession session = getSqlSession(); // when the call comes from refreshList(), session is null
session.selectList("PAYMENT.getAll", null);
}
}
in web.xml
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
If I change the STATE_SAVING_METHOD to server the application works fine but is not what I want. Same thing if I make the ManageBean as RequestScope but this too will penalize my requirements.
Thank you in advance to anyone for any kind of help! Ermal
回答1:
Solved the error adding <aop:scoped-proxy proxy-target-class="false" />
to the definition of the service/manager declared through Spring. This makes possible the injection of a fully serializable proxy instance.
<bean id="purchaseManager" class="al.ozone.bl.manager.impl.PurchaseManagerImpl">
<property name="purchaseDAO" ref="purchaseDAO" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
proxy-target-class="false"
is for telling that PurchaseManagerImpl
implements already an interface. If setted to true
or omitted, CGLIB2 library must be used.
In this way JSF is correctly taking data from DB using Spring+MyBatis.
The mistery (for me) on this point (more theorical) is :
- Is MyBatis object (
PurchaseDAOImpl
) and thedataSource
, correctly handled behind the scenes? - Are they recreated or restored on each HTTP request?
Remember that I have STATE_SAVING_METHOD=client
and BackingBean as ViewScope
.
My Goal is to have the server lighter possible because I expect an hight number of user interactions.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="poolPreparedStatements" value="true" />
<property name="defaultAutoCommit" value="false" />
</bean>
Thank you very much to anyone for some light on this matter!
Consulted links:
Spring session-scoped beans (controllers) and references to services, in terms of serialization
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes-other-injection
http://www.infoq.com/presentations/Whats-New-in-Spring-3.0
来源:https://stackoverflow.com/questions/9986197/jsf-managedbean-injected-properties-not-working-correctly-on-state-saving-meth