14

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

有没有人对此有解决方案(设计模式或成语级别)?

谢谢!

伊戈尔

4

6 回答 6

20

使用 JPA,默认构造函数是必需的,但是,您不需要使用 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; }
于 2009-06-23T16:51:28.020 回答
7

事实上,您应该同时拥有一个无参数构造函数以及 getter 和 setter 方法。要求在规范的第 2.1 节中说明。

在我的副本中的第 17 页上可以找到无参数构造函数要求:

实体类必须有一个无参数构造函数。实体类也可能有其他构造函数。无参数构造函数必须是公共的或受保护的。

第 18 页对访问器方法有要求:

实体的持久状态由实例变量表示,它可能对应于 Java-Beans 属性。实例变量只能由实体实例本身从实体的方法中直接访问。实体的客户端不得访问实例变量。实体的状态只能通过实体的访问器方法(getter/setter 方法)或其他业务方法提供给客户端。实例变量必须是私有的、受保护的或包可见性。

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

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

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

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

于 2009-07-01T20:41:00.423 回答
3

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

我们很清楚,JPA 规范中规定了该要求。上一个答案说您可以将无参数 ctor 设为私有,但这不符合规范(我看到链接指向 Hibernate 特定页面)。该规范规定实体必须具有公共或受保护的无参数 ctor。

-瑞克

于 2009-06-25T21:57:15.173 回答
2

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

公共类人{
 私人字符串名;
 私人字符串姓氏;

 公共人员(字符串名字,字符串姓氏){
  设置名字(名字);
  设置姓氏(姓氏);
 }

 // 用于休眠的私有无参数构造函数。
 私人人(){

 }

 公共字符串 getFirstName() {
  返回名字;
 }
 公共字符串 getLastName() {
  返回姓氏;
 }

 //休眠的私有设置器
 私人无效 setFirstName(字符串 nme){
  名字 = nme;
 }
 私人无效 setLastName(字符串 nme){
  姓氏 = nme;
 }
}

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

于 2009-06-24T21:16:18.693 回答
1

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

——安迪(数据

于 2009-06-22T18:59:14.190 回答
0

是的,持久化字段而不是属性,但是通常不想要默认构造函数(除非字节码增强器做了一些技巧),你不会摆脱它。

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

于 2009-06-23T16:27:35.193 回答