I have a web application in Struts and am trying to avoid the Domain-Model-view mismatch and am
running into some design issues that I require direction on. I am using the following link as a reference
http://www.javaworld.com/javaworld/jw-0 ... truts.html
Model Objects:
Code:
class Cat {
private Integer id;
private String name;
// Relation, Cat-> is associated with a- >CatType
private CatType catType;
......
}
class CatType {
private Integer typeId;
private String name;
private Set commonAfflictions;
...
}
Table:
Cat
----------------------
ID .....TYPE_ID (FK)
----------------------
Cat_Type
-----------------------
TYPE_ID NAME......
----------------------
In my web page, when creating/editing a Cat, the
user can select from a drop down of CatTypes. The Cat Type object
contains other information such as many-to-many, name, description etc.
I have the following layers, DAO, Service and Web:
Code:
public class CatDAOImpl ...{
public void save(Cat cat) {
getHibernateTemplate().saveOrUpdate(cat);
}
public Cat findCat(Integer id) {
return getHibernateTemplate()..;
}
public List getCatTypes() {
return ...;
}
}
public class CatService {
private CatDAO dao;
....
public void save(Cat cat) {
dao.save(cat);
}
public Cat findCat(Integer id) {
return dao.findCat(id);
}
public List getCatTypes() {
return dao.getCatTypes();
}
}
In my web layer:
Code:
public class CatForm extends ActionForm {
private String catId;
private String catName;
......
......
// Note that I am preventing a mismatch between the domain model
// and HTML page here by directly using the catType object.
// I could use a Integer catTypeId here but would rather not.
private CatType catType;
private List catTypes;
....
}
public class CatAction extends DispatchAction {
private CatService catService;
public void save(.....) {
CatForm catForm = (CatForm) form;
Cat catToSave = new Cat();
// CatType object created below will not contain the name of the type
// and other attributes of the CatType object. Only
// id is propagated.
BeanUtils.copyProperties(cat, catForm);
catService.save(catToSave);
......
}
public void edit(...) {
Cat cat = catService.getCat(id);
List catTypes = catService.getCatTypes();
CatForm f = new CatForm();
BeanUtils.copyProperties(catForm, cat);
f.setCatTypes(catTypes);
....
}
}
cat.jsp:
.....
<html:select name="catForm" property="catType.id">
<c:forEach items="${catForm.catTypes}" var="type">
<html:option value='${type.id}'>
<c:out value='${type.name}' />
</html:option>
</c:forEach>
</html:select>
I am trying to use the model object for CatType in the view layer directly as I do not see value in converting it to a view bean.
Anyway, in my Action class, when I do a BeanUtils.copyProperties(), the catType object
within the Cat object object
will only contain the "id" ; all other parts of the Cat type object will
be null such as commonAfflictions, name, description etc as the form does not contain other CatType information.
I am of the opinion that the catType object should be totally populated otherwise any call to access its properties will be null in layers downstream.
In my save() action class, I could do the following:
Code:
String selectedCatTypeId = catForm.getCatType().getId();
// Get the full type object from the database
CatType type = service.getCatType(selectedCatTypeId);
// Set the type on the cat, now type will have all attributes, whether
// the type is lazily loaded or not.
catToSave.setType(type);
service.save(catToSave);
This above code would cause an extra select and custom assembly of the catType object into the Cat object. If other objects like CatType i.e., reference data types, are introduced into
the Cat class, the above becomes as issue as we need to indivdually load each reference data type.
Please provide your input, suggestions and thoughts on what is the best way to tackle the above mismatch issues?