1

SINGLE_TABLEレガシー データベースをマッピングしています。そのうちの 1 つのテーブルは、識別子列を使用したマッピングを使用して継承階層に自然にマップされます。問題は、膨大な数の識別子の値があることです! (また、新しいものが時々追加され、アプリはポリモーフィック クエリでそれらを自動的に取得する必要があります)。私のアプリの観点からは、これらの異なる型の大部分を同じように扱いたいと思います (つまり、継承階層の基本クラスにマップするだけです)。ただし、一部については、特定のサブクラスにマップしたいと考えています。問題は、JPA が@DiscriminatorValue基本クラスに固有のものを 1 つ提供することを要求しているように見えることです (そうでなければ、デフォルトのものを生成します)。

具体的には:

@Entity
@Table("products")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "product_type")
@DiscriminatorValue( *anything not specified elsewhere!* )
public class Product {
    ...
    public double calculateMarkup() { ... default impl ... }
}
@Entity
@DiscriminatorValue("ProductA")
public class ProductA extends Product {
    ...
    @Override public double calculateMarkup() { ... specific impl ... }
}

これを JPA (または Hibernate 3.3 固有の拡張機能) でエレガントにマップする方法はありますか? 私ができる唯一の解決策は、継承を放棄し、特別な場合にその値を内部的に切り替える通常のフィールドとして列をマップすることですが、それは不自然で少し汚いと感じます。

4

3 に答える 3

1

JPAでこれをエレガントにマッピングする方法はありますか

いいえ、私が知っていることではありません。問題がデータ レイヤー (つまり、データまたはデータベース) で発生している場合は、そのレイヤーで解決しようとします。以下の 2 つの方法のいずれかを試してください。

  • 「他の場所で指定されていないもの」がデフォルトの識別子にマップされることを除いて、テーブルと同一のビューをデータベースに作成します*
  • Product各レコードの識別子の値を修正するテーブルに挿入時/更新時のトリガーを書き込みます*。

*たとえば、Oracle は範囲 A から範囲 B に if-then-else のように値をマップするDECODEを提供します。

于 2013-05-10T20:11:13.313 に答える
0

@ClassExtractor の使用を検討してください: http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Entities/Inheritance#Example:_Using_ClassExtractor_do_define_inheritance

何かのようなもの

public class ProductExtractor implements ClassExtractor {
    public void extractClassFromRow(Record row, Session session) {
        if (row.get("product_type").equals("ProductA")) {
            return ProductA.class;
        } 
        return Product.class;
    }
}

次に、クラスのカスタマイザーを作成し、それらに注釈を付けます。

于 2014-08-05T19:32:07.457 に答える