JPA Entites 上的空构造函数和设置器
我不喜欢 JPA 实体上至少有一个空构造函数和公共设置器的要求。 虽然我理解 EntityManager 方面的问题,但这会使类不变量无效。
有人有解决方案吗(设计模式或习惯用法级别)?
谢谢!
伊戈尔
I don't like the requirement on have at least one empty constructor and public setters on JPA entities. While I understand the issue on the EntityManager side, this invalidates class invariants.
Does anyone have a solution for this (design pattern or idiom level) ?
Thanks!
Igor
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
对于 JPA,默认构造函数是必需的,但是,您不需要使用 setter。 您可以根据注释的放置位置选择属性访问策略(字段或方法)。
以下代码将使用直接字段访问,并且将作为没有 setter 的实体的一部分工作:
与使用 setter 的方法访问:
With JPA, the default constructor is required, however, you are not required to use setters. You can choose a property access strategy(field or method) based on where you place the annotations.
The following code will use direct field access and will work as a part of an entity without a setter:
Versus method access with a setter:
事实上,您应该同时拥有无参数构造函数和 getter 和 setter 方法。 这些要求在 规格。
无参数构造函数要求可以在我的副本的第 17 页找到:
第 18 页对访问器方法有要求:
字段与属性访问指示 JPA 提供程序如何与您的实体交互,而不是客户端应用程序如何与其交互。 客户端应始终使用 get 和 set 方法。
一些 JPA 提供商在这些要求方面更为宽松,您可以将构造函数设为私有(如上所述)给特定供应商。 不过,该应用程序可能不可移植,因此如果您将来迁移,您可能会感到惊讶。
所以我不建议完全省略这些方法。 为了解决这个问题,我将 public no-arg ctor 标记为已弃用(在 javadoc 中放入有关它仅供 JPA 提供程序使用的内容)。 set 方法可以包含您想要维护不变量的逻辑。
它并不理想,但它应该可以防止意外使用错误的构造函数(我假设您有一个设置不变量的构造函数)。
In point of fact you should have both a no-args constructor and getter and setter methods. The requirements are indicated in section 2.1 of the spec.
The no-arg constructor requirement is found on page 17 in my copy :
Page 18 has the requirement for accessor methods :
Field vs. Property access indicates how the JPA provider interacts with your entity, not how the client application interacts with it. The client should always use get and set methods.
Some JPA providers are more lenient in these requirements and you may be able to make the constructor private (as suggested above) with a specific vendor. The application might not be portable though so you could be in for a surprise if you migrate in the future.
So I wouldn't recommend omitting the methods entirely. In order to resolve the problem I'd mark the public no-arg ctor as deprecated (put something in the javadoc about it being for JPA provider use only). The set methods can contain the logic you want to maintain your invariants.
It isn't ideal but it should prevent the wrong ctor from being used by accident (I'm assuming you have a ctor that sets the invariants).
OpenJPA 可以添加无参数构造函数作为增强实体的一部分。
我们很清楚,JPA 规范中强制要求了该要求。 前面的答案说您可以将无参数构造函数设为私有,但这不符合规范(我看到链接指向 Hibernate 特定页面)。 该规范规定实体必须具有公共或受保护的无参数对象。
-瑞克
OpenJPA can add a no-arg ctor as a part of enhancing your entities.
Just so we're clear, the requirement is mandated in the JPA spec. The previous answer says that you can make the no-arg ctor private, but that is not compliant with the spec(I see the link points to a Hibernate specific page). The spec states that an Entity must have a public or protected no-arg ctor.
-Rick
使用 DataNucleus,如果您不想,则不必添加默认构造函数; 它将通过字节码增强自动添加。 您还可以保留字段而不是属性,因此不需要公共设置器。
--Andy (DataNucleus)
With DataNucleus you don't have to add a default constructor if you don't want to; it will be added automatically by bytecode enhancement. Also you could persist fields instead of properties, hence no need for public setters.
--Andy (DataNucleus)
只需将您的构造函数设置为受保护或私有,这样您就可以保留类不变量!
请参阅http://www.javalobby.org/java/forums/m91937279.html
Just make your constructor protected or private, so you preserve the class invariants!
see http://www.javalobby.org/java/forums/m91937279.html for details.
是的,保留字段而不是属性,但是如果您不需要默认构造函数,通常(除非字节码增强器做了一些技巧)您将无法摆脱它。
您必须允许 jpa 实现实例化该类,因此公共默认构造函数是必需的。
Yes, persist fields instead of properties, but on the not wanting a default constructor you're typically (unless the byte code enhancer does some trick) you're not going to get away from it.
You have to allow your jpa implementation to instantiate the class, so a public default constructor is mandatory.