根据上述文档:
如果要映射到现有数据库,并且表没有区分符列,您仍然可以使用
@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()。可以使用设置这些expression对象DescriptorCustomizer。
类提取器必须能够确定并从数据库行返回类类型。通常,我们需要替换一个鉴别符列,即
- 列名对于给定的实体类型是唯一的
- 基于根实体给定列的值的条件
假设层次结构中的每个继承实体类型都有一个具有唯一名称的列:
@Entitypublic class Client extends Person { @Column(name = "CLIENT_SPECIFIC") private String clientSpecific; // ...}@Entitypublic 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
polymorphicResults = em.createQuery(“SELECt p FROM Person p”)
.getResultList();分别检索会员或客户列表
List concreteResults = em.createQuery(“SELECt a FROM Affiliate a”)
.getResultList();List
concreteResults = em.createQuery(“SELECt c FROM Client c”)
.getResultList();



