【问题标题】:How to get parent entity?如何获得父实体?
【发布时间】:2012-08-06 18:01:00
【问题描述】:

我将 JPA 2 与 Hibernate 一起使用。有两个实体类,CardElementIdentityDocumentKind。最后一个是第一个的继承实体。使用 SINGLE_TABLE 继承策略。当我尝试通过查询from CardElement where id = '123456' 选择父类的实例时,出现以下错误:

ID 为 123456 的对象不属于指定的子类: org.cp.cardsystem.CardElement(鉴别器:SDocClass)

我没有“SDocClass”鉴别器值的子类。实际上,在开发IdentityDocumentKind 的那一刻,CardElement 的类查询已在整个应用程序中广泛使用。所以我不能为每个鉴别器值创建CardElement 的子类,并在所有现有查询中用它替换CardElement。对我来说,这将花费太多的努力。使用 SINGLE_TABLE 继承策略时,有没有办法实例化父实体类?

【问题讨论】:

    标签: java hibernate jpa-2.0 java-ee-6


    【解决方案1】:

    我不确定我是否正确理解了您的问题。您正在使用单表策略来存储整个继承层次结构。但是,您只映射了一些鉴别器,而这一次,是未映射的鉴别器导致了问题(因为 Hibernate 不知道该子类的含义)。我是否正确理解了您的问题?

    考虑使用特殊的数据库视图而不是真实表。该视图仅公开具有您可以处理的鉴别器的记录。

    【讨论】:

    • 是的,您已经正确理解了我的问题。但是使用这样的数据库视图而不是表会使所有具有未映射鉴别器的记录都无法通过 CardElement 访问。通过 CardElement 实体类提供处理所有现有数据的可能性非常重要。
    • 但是您希望如何提供访问权限?您不想创建相应的子类,那么您应该如何授予访问权限?为什么你不能为每个鉴别器的值创建一个孩子(即使它只是一个扩展你的父级的空类也可以),或者不管 IdentityDocumentKind 为你忘记继承。只需将该字段视为属性
    • 在创建 IdentityDocumantKind 时,我认为可以处理具有未映射鉴别器作为 CardElement 实例的记录。我可以为每个鉴别器值创建继承的实体。但它需要在所有已经使用 CardElement 访问数据的应用程序中重构大量代码。此代码在开发 IdentityDocumentKind 时已经存在。
    • 如果您只关心数据访问,我相信您不需要进行任何重构。因为每个子类都继承自 CardElement,也就是说,这样的子类“是一个”CardElement。用户仍然可以将其视为 CardElement(这就是多态的美妙之处不是吗?)
    • 你是对的。不需要重构。就我而言,现在为每个鉴别器值创建一个后代就足够了。乍一看,与 CardElement 一起使用的现有代码不会受到影响。感谢这个好主意。然而,这种解决方案会导致另一个潜在问题。在运行时创建具有新鉴别器值的 CardElement 实例是不可能的。所有鉴别器值都必须在开发时定义。有什么解决方法吗?
    【解决方案2】:

    问题解决了。我以这种方式注释了继承层次结构的根实体类(CardElement):@DiscriminatorValue(value = "not null")。现在我可以选择此类的对象,而无需为每个鉴别器值创建子类。 not nullnull 似乎是 Hibernate 的特殊鉴别器值,它们在鉴别器列中匹配除 null 和 null 之外的任何内容。我在 Hibernate 的官方文档中没有找到关于这些值的任何信息。所以它可能是某种未记录的功能。

    【讨论】:

      猜你喜欢
      • 2017-11-10
      • 2014-05-27
      • 2017-09-27
      • 1970-01-01
      • 2023-01-15
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多