JPA Entites上的空构造函数和setter

13 entity jpa invariants

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

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

谢谢!

伊戈尔

小智 18

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

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

@Column(name = DESCRIPTION)
private String description;

public String getDescription() { return description; }
Run Code Online (Sandbox Code Playgroud)

使用setter访问方法:

private String description;

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

public String getDescription() { return description; }
Run Code Online (Sandbox Code Playgroud)

  • 请注意,JPA 并不要求无参数构造函数必须是公共的。它可以是公共的或受保护的。因此,受保护的默认构造函数可用于避免在没有外部参数的情况下进行实例化 (2认同)

Mik*_*ike 7

事实上,你应该同时使用no-args构造函数和getter和setter方法.要求见规范 2.1节.

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

实体类必须具有无参数构造函数.实体类也可以有其他构造函数.no-arg构造函数必须是公共的或受保护的.

第18页有访问者方法的要求:

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

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

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

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

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

  • 您引用的第二个引用只声明用户应用程序中的其他类不应直接访问实体的字段.它没有强制要求JPA提供者存在访问者.事实上,下一句话是"持久性提供程序运行时通过JavaBeans样式属性访问器("属性访问")或通过实例变量("字段访问")访问实体的持久状态.对我来说,这似乎很清楚,如果您使用字段访问,则不需要访问器,从而允许您拥有只读变量. (2认同)

Dat*_*eus 1

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

——安迪(DataNucleus