EclipseLink JPA继承没有鉴别器列 [英] EclipseLink JPA inheritance without discriminator column
问题描述
我有一个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 theClassExtractor
interface. An instance of this class is used to determine the class type to use for a database row. The class extractor must define aextractClassFromRow()
method that takes the databaseRecord
andSession
.
我们需要使用用户注释层次结构中的根实体使用类提取器定义:
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 anonlyInstancesExpression()
orwithAllSubclassesExpression()
for branch classes. These can be set toExpression
objects using aDescriptorCustomizer
.
类提取器必须能够从数据库行确定并返回类类型。
一般来说,我们需要更换一个鉴别器列,即
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屋!