I have seen examples that show how to do CRUD with one domain object without nested domain objects (just primitives). The problem is how to do the same thing with a domain object that has references to other domain objects. Giving the following example:
@Entity
public class Person implements Serializable {
@Id
private Long id;
private String name;
private Integer age;
private Address address;
private MaritalStatus maritalStatus;
... //getters/setters
}
@Entity
public class MaritalStatus implements Serializable {
@Id
private Long id;
private String description;
... //getters/setters
}
@Entity
public class Address implements Serializable {
@Id
private Long id;
private String street;
private String state;
private String zip;
... //getters/setters
}
Let's say I have a form which creates or update a Person and ask for the following inputs:
Name: __
Age: _____
Street: ___
State: _____
Zip: ____
Marital Status: (a select input with the corresponding key(id of the entity)/value)
So how do you create or update having nested properties which has their own identity too (persisted in another table).
I was thinking something like this using the prepare method and paramsPrepareParamsStack:
public class PersonAction extends ActionSupport {
public String save() {
personService.save(person);
return SUCCESS;
}
public String update() {
personService.update(person);
return SUCCESS;
}
public void prepare() {
if (person.getId() != null) {
//find the person using the id.
Person p = personService.findById(person.getId());
//Update th开发者_开发问答e reference to the selected martial status
//find the maritalstatus selected from the select box
MaritalStatus maritalStatus =
maritalStatusSerivce.findById(person.getMaritalStatus().getId());
//set the reference to the obtained person
p.setMaritalStatus(maritalStatus);
//find the address (in case it already exist)
if (person.getAddress().getId() != null) {
//find the address
Address address = addressService.findById(person.getAddress().getId());
//set the reference
p.setAddress(address);
}
//finally set the obtained reference to the action person property
this.person = p;
} else { //New person
//Find the address for the person
if (person.getAddress().getId() != null) {
//Only set the reference to the selected marital status
//find the maritalstatus selected from the select box
MaritalStatus maritalStatus =
maritalStatusSerivce.findById(person.getMaritalStatus().getId());
//set the reference to the person
person.setMaritalStatus(maritalStatus);
}
}
}
private Person person;
//getter/setters
}
Is that the correct way? Any other suggested approach?
Thanks
I have a few suggestions
I question whether MaritalStatus and Address need to be their own entities. Would you ever have an address or marital status independently from a Person? If yes, then ok, if no, you should make MaritalStatus and Address components
Most of the code in your action should be in another service. I would recommend creating some sort of facade service that coordinates all those operations and move it into a separate layer. I am basically saying move the prepare method to a service. A Struts action is really for just invoking services, which you are doing, however the way you are invoking the services is business logic, which should be in a service. Actions should just handle the requests, invoke the business logic, and return a response. Your facade service would have all the services it needs to do its stuff.
One benefit of that approach is that you can then reuse the operation. As it stands right now, if you wanted another action to do the same business operation you would have some refactoring to do.
The answer to your specific question is mostly in number 2 -- you create a service that takes all the arguments it needs to coordinate the creation and/or updates of the underlying entities.
精彩评论