Reputation: 1177
Form field is not automatically getting populated for below scenario
public class EmployeeAction extends ActionSupport implements ModelDriven{
private Employee employee=new Employee();
public Object getModel() {
return employee;
}
public String execute() throws Exception {
employee=employeeService.findById(employee.getId());
return super.execute();
}
}
the problem is new employee object but form is expecting old object reference , so manual mapping is working fine,
public String execute() throws Exception {
BeanUtils.copyProperties(employee,employeeService.findById(employee.getId()));
return super.execute();
}
how to avoid this object(new/old) reference problem
Employee.jsp
<s:form action="saveemployee" method="post">
<s:hidden name="id"></s:hidden>
<s:textfield name="name" label="Name" />
<s:textfield name="age" label="Age"></s:textfield>
<s:radio name="gender" label="Gender" list="%{staticMasterMap.gender}" listKey="key" listValue="value" ></s:radio>
<s:label value="DOB"></s:label><fw:datepicker name="dob" id="dob" changeMonth="true" changeYear="true" format="dd/mm/yy" yearRange="1900:2010"></fw:datepicker>
<s:textarea name="address" label="Address"></s:textarea>
<s:submit label="Save"></s:submit>
<s:reset label="Reset"></s:reset>
</s:form>
Struts.xml
<package name="fw" extends="struts-default" namespace="/">
<action name="saveemployee" class="com.example.employee.action.EmployeeAction"
method="save">
<result name="input" type="tiles">employee</result>
<result name="success" type="tiles">employee</result>
</action>
<action name="findemployee" class="com.example.employee.action.EmployeeAction" method="findById">
<result name="success" type="tiles">employee</result>
<result name="input" type="tiles">employee</result>
</action>
</package>
Upvotes: 3
Views: 3751
Reputation: 7344
I think the problem is simpler. By default, Struts 2 actions are instanced in each request (also written as having a scope of a request).
Employee
an instance of EmployeeAction
is created and used to populate the form.EmployeeAction
is created with a new (empty) Employee
instance.You could verify if this is the case by having a constructor log something or using a debugger.
Solving this could be done by saving information to the Session
(the employee id, for example) and verifying this data to create a new Employee instead.
Other option is to change the ObjectFactory of Struts 2 to something like Spring.
References: I've used Struts2 with and without Spring and tried to find some official reference. Struts 2 documentation is not clear about the instance creation in the request cycle but the documentation for the Spring plugin of Struts 2 says
Spring 2's bean scope feature can be used to scope an Action instance to the session, application, or a custom scope, providing advanced customization above the default per-request scoping.
Upvotes: 1
Reputation: 23587
I have not much worked with Struts2 Model Driven Interface and can not recommend what best can be done in your case, but if i am right this is one of the pitfalls of using the Model Driven Interface.
In your case by the time the execute()
method has been invoked S2 already has obtained a reference to your Model object which it will use for this particular request cycle. This means you're changing the reference inside your execute method using
employee=employeeService.findById(9l);
but still the framework has reference to the old model object. Since S2 gets the reference using the getter method it has no information what you are doing inside execute method and which is the cause of your data inconsistency.
Honestly i am not sure about any solution for this use-case and will go for a simple Object backed property approach. Hope some one can provide a workaround if my inputs are correct.
Upvotes: 3