JSF ManagedBean - injected properties not working correctly on STATE_SAVING_METHOD=client

我怕爱的太早我们不能终老 提交于 2019-12-12 06:39:49

问题


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 the dataSource, 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!