【问题标题】:Why is "public" not allowed for properties in JPA entities?为什么 JPA 实体中的属性不允许“公共”?
【发布时间】:2010-01-11 09:21:54
【问题描述】:

JPA 2.0 specification 在第 22 页上说:

类的实例变量必须 是私有的、受保护的或打包的 可见性独立于是否 字段访问或属性访问是 用过的。当使用属性访问时, 属性访问器方法必须是 公开或受保护。

为什么不允许公共访问?

【问题讨论】:

    标签: java jpa jakarta-ee


    【解决方案1】:

    使用公共字段,代理将无法可靠地工作——如果有人直接访问一个字段,那么持久性框架就没有简单的方法来拦截该调用并(例如)初始化包含对象,如果这是一个代理。

    如果无法访问字段,则可以在代理对象上生成合成 getter 方法以拦截方法调用并执行任何所需的“幕后”工作。

    【讨论】:

    • 代理无法可靠地工作
    • 同意Martin K,字节码增强也解决了问题——查看其他答案
    • 我应该更清楚,但我后来确实说过“没有简单方式”。在某种程度上,JPA 规范是不同框架之间的“最低公分母”——要求框架使用 AOP,或增强 calling 类(正如我收集的 DataNucleus 所做的那样)肯定是过分的对于 JPA 规范。我猜,其他持久性引擎欢迎提供超出 JPA 指定的功能,但要求为 JPA 规范合规性进行字段访问拦截将是……繁重的。
    • 可能更重要的是,Java 中的一些框架和工具隐藏了 get 和 set 部分,在我看来,这适用于表达式语言,例如在 JSP、JSF 和 Facelets 中使用。如果该字段是公开的,那么现在除了远程读心术之外,现在还有办法区分程序员的意思是哪一个。
    【解决方案2】:

    使用 DataNucleus 作为 JPA 提供者,您可以使用公共字段,但是您需要将访问这些字段的任何类标记为“持久性感知”(请参阅​​ DataNucleus 文档),这样它们就可以增强以迎合这一点

    【讨论】:

      【解决方案3】:

      确保使用访问器方法(如 get... set.... is.... )。这是隔离原则的一部分。

      【讨论】:

      • 但是 JPA 是否有技术要求来强制执行这种(有时只是伪)封装?
      • 这是 API 设计。许多实现处理惰性代理等。处理方法访问树和子类比处理属性访问要容易得多。
      猜你喜欢
      • 1970-01-01
      • 2017-08-10
      • 1970-01-01
      • 2021-01-09
      • 2012-01-27
      • 2011-04-26
      • 1970-01-01
      • 2015-02-06
      • 1970-01-01
      相关资源
      最近更新 更多