我不喜欢在 JPA 实体上至少有一个空的构造函数和公共设置器的要求。虽然我了解 EntityManager 方面的问题,但这会使类不变量无效。
有没有人对此有解决方案(设计模式或成语级别)?
谢谢!
伊戈尔
我不喜欢在 JPA 实体上至少有一个空的构造函数和公共设置器的要求。虽然我了解 EntityManager 方面的问题,但这会使类不变量无效。
有没有人对此有解决方案(设计模式或成语级别)?
谢谢!
伊戈尔
使用 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; }
事实上,您应该同时拥有一个无参数构造函数以及 getter 和 setter 方法。要求在规范的第 2.1 节中说明。
在我的副本中的第 17 页上可以找到无参数构造函数要求:
实体类必须有一个无参数构造函数。实体类也可能有其他构造函数。无参数构造函数必须是公共的或受保护的。
第 18 页对访问器方法有要求:
实体的持久状态由实例变量表示,它可能对应于 Java-Beans 属性。实例变量只能由实体实例本身从实体的方法中直接访问。实体的客户端不得访问实例变量。实体的状态只能通过实体的访问器方法(getter/setter 方法)或其他业务方法提供给客户端。实例变量必须是私有的、受保护的或包可见性。
字段与属性访问指示 JPA 提供者如何与您的实体交互,而不是客户端应用程序如何与其交互。客户端应始终使用 get 和 set 方法。
一些 JPA 提供者在这些要求上更为宽松,您可以将构造函数设为私有(如上文所建议的)与特定供应商。该应用程序可能无法移植,因此如果您将来迁移,您可能会感到惊讶。
所以我不建议完全省略这些方法。为了解决这个问题,我将 public no-arg ctor 标记为已弃用(在 javadoc 中添加一些内容,说明它仅供 JPA 提供者使用)。set 方法可以包含您想要维护不变量的逻辑。
这并不理想,但它应该防止意外使用错误的 ctor(我假设您有一个设置不变量的 ctor)。
OpenJPA 可以添加无参数 ctor 作为增强实体的一部分。
我们很清楚,JPA 规范中规定了该要求。上一个答案说您可以将无参数 ctor 设为私有,但这不符合规范(我看到链接指向 Hibernate 特定页面)。该规范规定实体必须具有公共或受保护的无参数 ctor。
-瑞克
只需使您的构造函数受保护或私有,这样您就可以保留类不变量!
公共类人{ 私人字符串名; 私人字符串姓氏; 公共人员(字符串名字,字符串姓氏){ 设置名字(名字); 设置姓氏(姓氏); } // 用于休眠的私有无参数构造函数。 私人人(){ } 公共字符串 getFirstName() { 返回名字; } 公共字符串 getLastName() { 返回姓氏; } //休眠的私有设置器 私人无效 setFirstName(字符串 nme){ 名字 = nme; } 私人无效 setLastName(字符串 nme){ 姓氏 = nme; } }
有关详细信息,请参阅http://www.javalobby.org/java/forums/m91937279.html。
如果您不想使用 DataNucleus,则不必添加默认构造函数;它将通过字节码增强自动添加。您也可以保留字段而不是属性,因此不需要公共设置器。
——安迪(数据核)
是的,持久化字段而不是属性,但是通常不想要默认构造函数(除非字节码增强器做了一些技巧),你不会摆脱它。
您必须允许您的 jpa 实现实例化该类,因此公共默认构造函数是强制性的。