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

私はあなたと同じ問題に直面しています。

エラー・メッセージは、LassoWarehandlingEntryまたはLassoWarehandlingEntryHistのどちらを問い合せているかをEclipseLinkが区別できないことを示しています。(クラス・インジケータ・フィールドまたはクラス抽出メソッドを設定する必要があります。)したがって、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 に答える