【问题标题】:EclipseLink JPA inheritance without discriminator columnEclipseLink JPA 继承无鉴别器列
【发布时间】:2014-04-20 06:19:22
【问题描述】:

我有一个继承自 Person 类的 Client 和 Affiliate 类。正在使用联合继承策略类型 - 它们每个都与父类共享主键。由于没有鉴别器列,我们选择使用DescriptorCustomizer and ClassExtractor。但它并没有真正说明它是如何工作的,而且代码似乎没有编译。如果有人用代码 sn-p 给出一个很好的例子来理解,那就太好了。

【问题讨论】:

  • “代码似乎无法编译” 把你的代码贴出来,让我们看看,找出根本原因不是更好吗?
  • @wypierprz EclipseLink 网站中给出的代码无法编译。在AirMilesExtractor 中,extractorClassFromRow() 具有void 返回类型,即使这样它也会返回Class。此外,目前尚不清楚它试图实现什么。

标签: java jpa eclipselink discriminator


【解决方案1】:

根据mentioned documentation

如果您要映射到现有数据库,并且表没有 一个鉴别器列,您仍然可以使用 @ClassExtractor 注释或 <class-extractor> 元素。班上 提取器采用实现ClassExtractor 的类 界面。该类的一个实例用于确定类 用于数据库行的类型。类提取器必须定义一个 extractClassFromRow() 获取数据库 Record 的方法和 Session.

我们需要使用类提取器定义用户定义的层次结构中的根实体:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@ClassExtractor(PersonClassExtractor.class)
public abstract class Person {
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    private int age;
    // ...
}

请注意,我们不使用 @Customizer 注释,因为在 JOINED 继承策略的情况下不需要这样做:

如果类提取器与SINGLE_TABLE 继承一起使用,则行 类类型的必须能够在查询中被过滤。这可以是 通过设置onlyInstancesExpression()withAllSubclassesExpression() 用于分支课程。这些可以设置 使用DescriptorCustomizerExpression 对象。

类提取器必须能够从数据库行中确定并返回类类型。 一般来说,我们需要替换一个鉴别器列,即

  • 列名对于给定的实体类型是唯一的
  • 基于根实体的给定列的值的条件

假设层次结构中每个继承的实体类型都有一个具有唯一名称的列:

@Entity
public class Client extends Person {
    @Column(name = "CLIENT_SPECIFIC")
    private String clientSpecific;
    // ...
}

@Entity
public class Affiliate extends Person {
    @Column(name = "AFFILIATE_SPECIFIC")
    private float affiliateSpecific;
    // ...
}

那么类提取器可能如下所示:

public class PersonClassExtractor extends ClassExtractor {
    @Override
    public Class<?> extractClassFromRow(Record databaseRow, Session session) {
        if (databaseRow.containsKey("CLIENT_SPECIFIC")) {
            return Client.class;
        } else if (databaseRow.containsKey("AFFILIATE_SPECIFIC")) {
            return Affiliate.class;
        } else {
            return Person.class; // this should never happen
        }
    }
}

  • 检索客户和附属公司列表
List<Person> polymorphicResults = em.createQuery("SELECT p FROM Person p")
                                    .getResultList();
  • 分别检索附属公司或客户的列表
List<Affiliate> concreteResults = em.createQuery("SELECT a FROM Affiliate a")
                                    .getResultList();

List<Client> concreteResults = em.createQuery("SELECT c FROM Client c")
                                 .getResultList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 2012-12-08
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多