【发布时间】:2013-11-14 08:28:06
【问题描述】:
我在我的EJB 中创建了entities 的包装器。在这个 wrapper 中,我有我的 business-logic 和我的 validations 共同点用于 entity。我想知道如何将我的 wrapper 发送到 CRUD(但我不希望我的 wrapper 成为@Entity)。
有什么想法???
【问题讨论】:
标签: inheritance jpa wrapper business-logic
我在我的EJB 中创建了entities 的包装器。在这个 wrapper 中,我有我的 business-logic 和我的 validations 共同点用于 entity。我想知道如何将我的 wrapper 发送到 CRUD(但我不希望我的 wrapper 成为@Entity)。
有什么想法???
【问题讨论】:
标签: inheritance jpa wrapper business-logic
最好不要将您的 EJB 用作包装器,而是使用其他具有特定目的的 java 类来包装实体。
包装类应该包装一个实体,因此它应该是一对一的关联(不要与 jpa 混淆,我的意思是 java 关联/组合)。所以基本上你遵循装饰器模式。
然后你创建你需要的所有方法,拥有与你要包装的实体相同的方法真的很有帮助。然后在方法体中调用你要包装的实体实例的相应方法。
示例,
@Entity
public class Person {
@Column(name = "ID")
private Long id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
public String getFirstName(){
return this.firstName;
}
public void setFirstName(String firstName){
this.firstName = firstName;
}
public String getLastName(){
return this.lastName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
}
public class PersonWrapper{
private Person person;
private String someCalculatedField;
public PersonWrapper(Person person){
this.person = person;
}
public Person getPerson(){
return this.person;
}
public void setPerson(Person person){
this.person = person;
}
public String getFirstName(){
/* possibly do transformations */
return person.getFirstName();
}
public void setFirstName(String firstName){
/* possibly do validations, transformations*/
person.setFirstName(firstName);
}
public String getSomeCalculatedField(){
/*do stuff with person or other entities as well and populate the calculated field,
then return it
*/
return this.someCalculatedField;
}
}
也许不清楚,但是在您完成 CRUD 函数或对包装器实例的任何其他操作之后,为了通过 jpa 持久化您的更改,您需要检索 jpa 实体(即 person 在您的情况下来自包装器的方法 getPerson() ) 并调用 persist 、 merge 、 remove 或对该实例的任何内容。
编辑
基于 cmets,我想明确表示,让包装器从实体继承只会有利于将非 jpa(例如 CRUD UI)代码与包装器本身分离,例如通过调用 Person person = new PersonWrapper(personEntity); 而不是PersonWrapper person = new PersonWrapper(personEntity);.
即使在继承之后,也必须重写包装器中的方法,因为包装器的方法体调用的是包装实例上的代码,而不是包装器本身上的代码。不覆盖方法将调用包装器本身的继承方法。后者是一个错误有两个原因,
1.数据从错误的实例中存储/检索(包装器不是包装的实体)
2.data 不应该存储在包装器中,因为它不能在 jpa 函数中使用,因为它不是实体(那里没有 jpa 继承),只能使用包装的实例。此外,包装器并非来自托管 jpa 上下文,因此它没有与持久性相关的数据。
【讨论】:
Person p = new PersonWrapper() 之类的代码中使用它。