我不喜欢JPA实体上至少有一个空构造函数和公共setter的要求。虽然我理解EntityManager方面的问题,但这会使类不变量无效。
有没有人有这方面的解决方案(设计模式或成语水平)?
谢谢!
伊戈尔
答案 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实现实例化该类,因此必须使用公共默认构造函数。