我有一个应该绑定到包含很多子节点的复杂对象的表单,每次在加载此表单之前,我必须在只有很多new
语句的方法中初始化所有子对象并调用setter
方法,我必须为许多表单和其他复杂对象重复此方案
是否有比initializeEmployee
方法更好的策略?
例如:
@Entity
public class Employee {
Integer Id;
Contract contract;
Name name;
List<Certificate> list;
// getter and setters
}
@Entity
public class Contract {
String telephoneNum;
String email;
Address address;
// getter and setters
}
@Entity
public class Address {
String streetName;
String streetNum;
String city;
}
public class Name {
String fName;
String mName;
String lName;
// getter and setters
}
// And another class for certificates
public initializeEmployee() {
Employee emplyee = new Employee();
Name name = new Name();
employee.setName(name);
Contract contract = new Contract();
Address address = new Address();
contract.setAddress(address);
employee.setContract(contract);
// set all other employee inner objects,
}
修改
根据以下答案,似乎没有最佳答案。但是,我可以使用实体constructor
或Factory
设计模式。
但是在使用Required和Optional字段初始化所有字段策略时,这两个解决方案都无法解决我的其他问题。
例如:
如果我根据需要Name
(即如果Name对象属性为空,则Employee实体不会持久化,另一方面Contract
实体是可选的。我不能保持空{{1}对象到数据库,所以我必须在持久化之前先使它Contract
,然后在持久性之后重新初始化它,如下所示
null
答案 0 :(得分:7)
你可以向你的实体添加构造函数(毕竟它们是它们的角色),如果空值对你的情况没有意义,就可以实例化这些字段。
另一种方式,如果你不喜欢添加构造函数,就是添加一个静态工厂方法来实现你的bean,它看起来像initializeEmployee()但是带有潜在的参数并返回一个Employee对象。 http://en.wikipedia.org/wiki/Factory_method_pattern
同样,您也可以实例化您的集合,因为空集合可能没有任何意义(但是有一个空集合)。
您可以向实体添加行为,不要被锁定在Anemic Domain Model中,这被Martin Fowler视为反模式http://www.martinfowler.com/bliki/AnemicDomainModel.html
修改
我看到你正在使用dao.persist(实体):你可能正在使用JPA。如果是这样,也许最好不要修改你的对象图(在正面)并为Employee添加一个EntityListener(在持久层中):这里是Hibernate EntityListener的链接(它是一个JPA特性,所以如果你是使用另一个框架不要担心)http://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/listeners.html
使用EntityListener,您可以在持久性和之后添加小的“aop like”操作。这将允许您不处理域和前层上的空值,并确保每个实体都适合任何情况(更好的验证)。
在PrePersist中:你们添加你的代码来检查空值(可能在域类上使用自定义方法“isEmpty()”)并在需要时使字段无效。在PostPersist中添加新对象。
答案 1 :(得分:4)
我无法得到你真正需要的东西,但我想你可以这样试试:
@Entity
public class Employee {
Integer Id;
Contract contract = new Contract();
Name name = new Name();
List<Certificate> list;
// getter and setters
}
@Entity
public class Contract {
String telephoneNum;
String email;
Address address = new Address();
// getter and setters
}
答案 2 :(得分:2)
我不确定它是否会降低详细程度,但由于这是一个UI问题,您可以初始化flow.xml中的可编辑对象,然后在保存到数据库之前将它们全部放在Employee实例中。
<on-start>
<evaluate expression="new foo.bar.Name()" result="flowScope.employeeName" />
<evaluate expression="new foo.bar.Contract()" result="flowScope.contract" />
<evaluate expression="new foo.bar.Address()" result="flowScope.address" />
</on-start>
答案 3 :(得分:1)
实际上我建议不要直接在GUI中使用Hibernate Entities。在许多情况下(我也假设你的,但我遗漏了一些关于你的用例的细节),使用数据传输对象模式是很有用的。您可以创建特定于GUI的DTO,只包含您需要的那些字段,并且结构只需要复杂。
在特定用户操作(例如保存)之后,使用这些DTO(在事件处理上)来创建将被保留的实体。
除非你的情况只是进入GUI屏幕导致实体创建,否则我会推荐工厂模式。
另请注意,在许多情况下,构成主对象(在您的示例中为Employee)的组件对象的初始化最好在主对象的构造函数中初始化,例如。如果您希望Contract不能为null - 在构造函数中初始化它。证书和其他人的名单也是如此。