EclipseLink JPA继承没有鉴别器列 [英] EclipseLink JPA inheritance without discriminator column

查看:176
本文介绍了EclipseLink JPA继承没有鉴别器列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Client and Affiliate class, inheriting from Person class. Joined inheritance strategy type is being used - each of them sharing primary key with the parent class. As there's no discriminator column we chose to use DescriptorCustomizer and ClassExtractor. But it doesn't really give any idea how it works, also, the code doesnt seem to compile. It would be nice if someone gives a nice example with code snippet for understanding.

推荐答案

根据提到的文档

如果要映射到现有数据库,并且表没有
a discriminator列,您仍然可以使用
@ClassExtractor <定义继承/ code>注释或< class-extractor> 元素。类
提取器接受一个实现 ClassExtractor
接口的类。此类的实例用于确定要用于数据库行的类
类型。类提取器必须定义一个
extractClassFromRow()方法,它接受数据库记录
会话

If you are mapping to an existing database, and the tables do not have a discriminator column you can still define inheritance using the @ClassExtractor annotation or <class-extractor> element. The class extractor takes a class that implements the ClassExtractor interface. An instance of this class is used to determine the class type to use for a database row. The class extractor must define a extractClassFromRow() method that takes the database Record and Session.

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

we need to annotate the root entity in a hierarchy with user defined using the class extractor:

@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 继承策略的情况下不需要这样做:

Notice that we don't use @Customizer annotations since as this is not required in case of JOINED inheritance strategy:


如果类提取器与 SINGLE_TABLE 继承一起使用,则类类型的行
必须能够要在查询中过滤。这可以通过为分支设置 onlyInstancesExpression()
withAllSubclassesExpression()来实现
类。可以使用 DescriptorCustomizer
设置为 Expression 对象。

If a class extractor is used with SINGLE_TABLE inheritance, the rows of the class type must be able to be filtered in queries. This can be accomplished by setting an onlyInstancesExpression() or withAllSubclassesExpression() for branch classes. These can be set to Expression objects using a DescriptorCustomizer.

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

The class extractor must be able to determine and return the class type from the database row. In general we need a replacement of a discriminator column, i.e.


  • 对于给定的实体类型而言唯一的列名

  • 基于根实体的给定列的值的条件

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

Suppose that each of inherited entity type in a hierarchy has a column with unique name:

@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;
    // ...
}

然后类提取器可能如下所示:

then class extractor may look as follows:

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();
      

      这篇关于EclipseLink JPA继承没有鉴别器列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆