JSF ManagedBean - injected properties not working

2019-09-20 05:32发布

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条回答
唯我独甜
2楼-- · 2019-09-20 06:17

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

查看更多
登录 后发表回答