1

これが私が解決策を見つけることができない問題であり、それは不可能であるか、アイデア全体で間違った方向に向かっていると思います。

私のJPA階層の最初の部分は次のようでした:

@MappedSuperclass
public abstract class AbstractEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;
    ..... 
}

@Audited
@Entity
@Table(name = "T_MEETING")
public class Meeting extends AbstractEntity implements Groupable {...}

@Audited
@Entity
@Table(name = "T_QUESTION")
public class Question extends AbstractEntity implements Groupable {...}

このデータベースは、一部のオブジェクトでカスタム フィールドが必要になるまで、しばらくの間使用されてきました。

私は次のルートに行くことにしました - カスタムフィールドを持つオブジェクトのベースとして抽象的なエンティティを貼り付けました:

@Audited
@Entity
@Table(name = "T_CF_OBJECT")
@Inheritance(strategy = InheritanceType.JOINED)
@PrimaryKeyJoinColumn(name = "ID", referencedColumnName = "CF_OBJECT_ID")
public abstract class EntityWithCustomFields extends AbstractEntity {...}

@Audited
@Entity
@Table(name = "T_QUESTION")
public class Question extends EntityWithCustomFields implements Groupable {...}

@Audited
@Entity
@Table(name = "T_MEETING")
public class Meeting extends EntityWithCustomFields implements Groupable {...}

私はさまざまなオプションを試しましたが、常に問題があります:

  1. JPAプロバイダー(私の場合は休止状態)は、最初に親を挿入するためCF_OBJECT_IDnull

    Hibernate: t_cf_object (id、cf_object_id) 値 (null、?) に挿入 Hibernate: t_meeting (active、date、c_group、last_notification_date、only_for_members、place、questions_order、subject、update_date、id) 値 (?、?、?、 ?, ?, ?, ?, ?, ?, ?)

  2. @PrimaryKeyJoinColumn基本エンティティの注釈を省略するIdと、そのId子孫の s が結合列として使用され、サブクラス テーブルに同じ ID がありません。これは最初は良いことですが、すでに両方のテーブルに大量のレコードがあり、id列には同じ値があります。idテーブル内の s を変更するオプションではありません。

私の場合、継承を使用する正しい方法は何ですか?可能な限りシームレスに取得できますか? 最初に休止状態でサブクラスのインスタンスを永続化し、その ID を永続化されたスーパークラスに渡す方法を見つけるとよいでしょう。そのための注釈が必要ですよね?

編集:使用する提案について@MappedSuperclass

@MappedSuperClass次の理由で、私は本当に a を使用できません。親クラスは、クラスからの関係EntityWithCustomFieldsによって参照するために使用されます。コードでは、次のようになります。ManyToOneCustomFieldValue

@Entity
@Audited
@Table(name = "T_CF_VALUES")
public class CustomFieldValue extends AbstractEntity {
    @ManyToOne
    @JoinColumn(name = "customFieldObject", nullable = false)
    private EntityWithCustomFields customFieldObject;
    ....
}
@Audited
@Entity
@Table(name = "T_CF_OBJECT")
@Inheritance(strategy = InheritanceType.JOINED)
@PrimaryKeyJoinColumn(name = "ID", referencedColumnName = "CF_OBJECT_ID")
public abstract class EntityWithCustomFields extends AbstractEntity {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "customFieldObject", cascade = CascadeType.ALL)
    private List<CustomFieldValue> customFields;
    ....
 }

こういうものには使えないと思います@MappedSuperclass

4

1 に答える 1

0

ここではエンティティの継承は必要ないようですが、カスタムフィールドを持つエンティティ用に追加のマップされたスーパークラスが必要です。

エンティティの継承は、実際の機能的な関係がある場合に使用する必要があります。たとえば、請求書に製品のリストが含まれている場合、製品エンティティは継承ツリー(野菜、肉、衣服など)のルートになります。この場合、Vegetableは製品であり、もちろん2つの製品が同じIDを持たない場合があります。これは、たとえば、Priceエンティティが外部キーを介して製品を参照でき、2つの製品が同じIDを持っている場合はそうではないためです。まったく機能しません。

あなたの場合、カスタムフィールドを持つエンティティは完全に無関係です。それらはたまたま共通のフィールドを持っているので、これらの共通のフィールドをスーパークラスに入れることによってこれを因数分解したいと思います。それがMappSuperclassの目的です。そして、それらのカスタムフィールドは、すべてのエンティティテーブルで複製する必要があります。とにかく、これは結合された継承よりもはるかに効率的です(これにより、クエリが増え、クエリをより複雑で最適化するのが難しくなります)。

于 2012-05-16T05:56:57.660 に答える