0

我已经花了几个小时试图完成这项工作。我正在使用历史记录策略为我的一些表创建完整的历史记录。这是在抽象类中定义的。然后我有一个普通实体实现这个类并定义它的字段。然后我想使用一个从上层类继承的类,但它的表设置为历史表。效果很好,唯一的问题是,当我对历史表(lasso_warehandling_entry)进行查询时,它总是从历史实体(lasso_warehandling_entry_hist)返回结果。所以我添加了线descriptor.getInheritancePolicy().setShouldReadSubclasses(false); 我在某处读到,它应该可以解决我的问题。不幸的是,它没有。现在我总是收到以下消息:

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
}
4

2 回答 2

0

我面临着和你一样的问题。

错误消息是说 EclipseLink 无法区分您是在查询 LassoWarehandlingEntry 还是 LassoWarehandlingEntryHist。(必须设置类指示符字段或类提取方法。)因此,如果您查询 LassoWarehandlingEntry,EclipseLink 将同时查询 LassoWarehandlingEntry 和 LassoWarehandlingEntryHist。所以我猜你正在尝试使用

descriptor.getInheritancePolicy().setShouldReadSubclasses(false);

不幸的是,由于我们使用的是 InheritanceType.TABLE_PER_CLASS,我们似乎不能使用鉴别器注释(@DiscriminatorColumn 和 @DiscriminatorValue)。这 2 个注解仅适用于 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 个查询。

希望这会有所帮助!

于 2014-03-29T07:32:20.973 回答
0

这应该有助于:

if (descriptor.hasInheritance()) {
    descriptor.getInheritancePolicy().setShouldReadSubclasses(false);
}

getInheritancePolicy()文档

使用此方法时必须小心,因为它会延迟初始化继承策略。

在不使用继承的描述符上调用它会导致问题,必须始终首先调用 hasInheritance()。

于 2019-08-15T18:54:37.843 回答