我已经花了几个小时试图完成这项工作。 我正在使用历史策略为我的一些表创建完整的历史记录。这是在抽象类中定义的。 然后我有一个正常的实体来实现这个类并定义它的字段。 然后我想使用一个从上层开始的类,但是它的表被设置为历史表。这是完美的,唯一的问题是,当我对历史表(lasso_warehandling_entry)进行查询时,它总是返回历史实体(lasso_warehandling_entry_hist)的结果。所以我添加了这条线 descriptor.getInheritancePolicy()setShouldReadSubclasses(假)。 我读到的地方,它应该解决我的问题。不幸的是它没有。 现在我总是得到以下信息:
Exception Description: The descriptor [RelationalDescriptor(dao.LassoWarehandlingEntry --> [DatabaseTable(lasso_warehandling_entry)])] has been set to use inheritance, but a class indicator field has not been defined.
When using inheritance, a class indicator field or class extraction method must be set.
Parent Descriptor: [RelationalDescriptor(org.rorotec.lasso.dao.LassoWarehandlingEntry --> [DatabaseTable(lasso_warehandling_entry)])]
Descriptor: RelationalDescriptor(dao.LassoWarehandlingEntry --> [DatabaseTable(lasso_warehandling_entry)])
由于我们为每个实体使用单独的表,因此使用指标字段没有多大意义。无论如何,我只是没有设法得到这个消息。 任何人都知道我应该如何解决这个问题? 代码看起来像这样:
@MappedSuperclass
@Customizer(abstractDao.HistoryCustomizer.class)
public abstract class AbstractAuditedOzlEntity {
// defined the columns all the autited classes have
...
}
public class HistoryCustomizer implements DescriptorCustomizer {
public void customize(ClassDescriptor descriptor) {
HistoryPolicy policy = new HistoryPolicy();
policy.addHistoryTableName(descriptor.getTableName() + "_hist");
policy.addStartFieldName("start_date");
policy.addEndFieldName("end_date");
descriptor.setHistoryPolicy(policy);
// This here I added afterwards, as described in the text, and is the reason for the error message i get
descriptor.getInheritancePolicy().setShouldReadSubclasses(false);
}
}
@Entity
// when i define the inhertiancetype already in the abstract class, it doesn't seem to have any influence, so I added it here.
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@Table(name = "lasso_warehandling_entry")
public class LassoWarehandlingEntry extends AbstractAuditedOzlEntity implements Serializable {
// define the specific stuff of this table
...
}
@Entity
@Table(name = "lasso_warehandling_entry_hist")
@AttributeOverride(name="id", column=@Column(name="hist_id"))
public class LassoWarehandlingEntryHist extends LassoWarehandlingEntry {
...
// add the columns which only exist in the history tables like end_date
}
答案 0 :(得分:0)
我面临与你相同的问题。
错误消息表明EclipseLink无法区分您是在查询LassoWarehandlingEntry还是LassoWarehandlingEntryHist。 (必须设置类指示符字段或类提取方法。)因此,如果查询LassoWarehandlingEntry,EclipseLink将同时查询LassoWarehandlingEntry和LassoWarehandlingEntryHist。所以我想你正在尝试使用
descriptor.getInheritancePolicy().setShouldReadSubclasses(false);
不幸的是,由于我们使用的是InheritanceType.TABLE_PER_CLASS,我们似乎无法使用鉴别器注释(@DiscriminatorColumn和@DiscriminatorValue)。这两个注释仅适用于InheritanceType.SINGLE_TABLE和InheritanceType.JOINED。 ClassExtractor也不起作用。有关详情,请访问https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Inheritance
无论如何,我通过创建一个抽象类来解决这个问题,该抽象类将由两个具体类继承。在你的情况下:
@MappedSuperclass
public abstract class AbstractLassoWarehandlingEntry extends AbstractAuditedOzlEntity implements Serializable {
// define the specific stuff of this table
...
}
@Entity
@Table(name = "lasso_warehandling_entry")
public class LassoWarehandlingEntry extends AbstractLassoWarehandlingEntry implements Serializable {
// Empty class as the content is already defined in AbstractLassoWarehandlingEntry
}
@Entity
@Table(name = "lasso_warehandling_entry_hist")
@AttributeOverride(name="id", column=@Column(name="hist_id"))
public class LassoWarehandlingEntryHist extends AbstractLassoWarehandlingEntry {
...
// add the columns which only exist in the history tables like end_date
}
通过使用此方法,您可以从HistoryCustomizer类中删除以下行。
descriptor.getInheritancePolicy().setShouldReadSubclasses(false);
现在,如果您查询LassoWarehandlingEntry,EclipseLink将只对LassoWarehandlingEntry表执行1次查询。
希望这有帮助!
答案 1 :(得分:0)
这应该有帮助:
if (descriptor.hasInheritance()) {
descriptor.getInheritancePolicy().setShouldReadSubclasses(false);
}
来自getInheritancePolicy()
documentation:
使用此方法时必须小心,因为它会延迟初始化继承策略。
在不使用继承的描述符上调用此方法会导致问题,必须始终首先调用hasInheritance()。