JPA实体上的空构造函数和setter

时间:2009-06-22 14:02:50

标签: jpa entity invariants

我不喜欢JPA实体上至少有一个空构造函数和公共setter的要求。虽然我理解EntityManager方面的问题,但这会使类不变量无效。

有没有人有这方面的解决方案(设计模式或成语水平)?

谢谢!

伊戈尔

6 个答案:

答案 0 :(得分:17)

使用JPA时,默认构造函数是必需的,但是,您不需要使用setter。您可以根据放置注释的位置选择属性访问策略(字段或方法)。

以下代码将使用直接字段访问,并将作为没有setter的实体的一部分:

@Column(name = DESCRIPTION)
private String description;

public String getDescription() { return description; }

使用setter访问方法:

private String description;

@Column(name = DESCRIPTION)
public void setDescription(String description) {
     this.description = description;
}

public String getDescription() { return description; }

答案 1 :(得分:6)

事实上,你应该同时使用no-args构造函数和getter以及setter方法。要求见spec第2.1节。

no-arg构造函数要求可在我的副本的第17页找到:

  

实体类必须具有无参数   构造函数。实体类可能有   其他建设者也是如此。没有arg   构造函数必须是公共的或   保护。

第18页要求使用访问者方法:

  

实体的持久状态是   由实例变量表示,   这可能对应于Java-Beans   属性。实例变量可以   只能从内部直接访问   实体的方法由   实体实例本身。例   不得访问变量   该实体的客户。的状态   该实体可供客户使用   只能通过实体的访问者   方法(getter / setter方法)或   其他商业方法。例   变量必须是私有的,受保护的,   或包装可见性。

字段与属性访问指示JPA提供程序如何与您的实体交互,而不是客户端应用程序如何与之交互。客户端应始终使用get和set方法。

某些JPA提供程序在这些要求中更宽松,您可以将构造函数设置为私有(如上所述)与特定供应商。该应用程序可能不是可移植的,因此如果您将来迁移,您可能会感到惊讶。

所以我不建议完全省略这些方法。为了解决这个问题,我将公共no-arg ctor标记为已弃用(在javadoc中添加一些关于它的内容仅供JPA提供者使用)。 set方法可以包含要维护不变量的逻辑。

这不是理想的但它应该防止错误的ctor被意外使用(我假设你有一个设置不变量的ctor)。

答案 2 :(得分:3)

OpenJPA可以添加无参数作为增强实体的一部分。

我们很清楚,这个要求是JPA规范中规定的。前面的答案说你可以将no-arg ctor设为私有,但这不符合规范(我看到链接指向Hibernate特定页面)。该规范规定,实体必须拥有公共或受保护的无法协议。

-Rick

答案 3 :(得分:2)

只需使您的构造函数受到保护或私有,因此您可以保留类不变量!

public class Person {
 private String firstName;
 private String lastName;

 public Person(String firstName, String lastName) {
  setFirstName(firstName);
  setLastName(lastName);
 }

 // private no-arg constructor for hibernate.
 private Person() {

 }

 public String getFirstName() {
  return firstName;
 }
 public String getLastName() {
  return lastName;
 }

 // private setters for hibernate
 private void setFirstName(String nme) {
  firstName = nme;
 }
 private void setLastName(String nme) {
  lastName = nme;
 }
}

有关详细信息,请参阅http://www.javalobby.org/java/forums/m91937279.html

答案 4 :(得分:1)

使用DataNucleus,如果你不想,你不必添加默认构造函数;它将通过字节码增强自动添加。此外,您可以保留字段而不是属性,因此不需要公共设置器。

- 安迪(DataNucleus

答案 5 :(得分:0)

是的,坚持字段而不是属性,但是在不想要默认构造函数的情况下(除非字节代码增强器做了一些技巧)你不会远离它。

您必须允许您的jpa实现实例化该类,因此必须使用公共默认构造函数。