2

私の質問は、その ID を保持するエンティティのタイプを変更することに非常に似ていますが、代わりに、Table_per_class の代わりに InheritanceType.JOINED を使用しています。

これは、スーパークラスと同じ ID を持つ新しいサブクラスを作成するためだけに、テーブルを変更しないことを意味します。

要約すると、Person クラスと、Person を拡張し、同じ ID を持つ Doctor があります。データベースから Person を取得し、それを Doctor にする必要があります。Person エンティティのすべてのデータを保持しますが、Doctor エンティティ用に追加のデータを作成します。

医師をマージしようとすると、新しい ID が生成されますが、これは私には有効ではありません。

これが私が最初に試したことです

private Person getDoctor(Person person) {
            // Person already a doctor ==> OK
    if (person instanceof Doctor) {
        return person;
    }
            // Transient Person ==> //Transient Doctor OK
    if (person == null) {
        return new Doctor();
    }
            // Creates a Doctor from the person (only setting id...),
            // and merges it ==>
            fails as the id changes.
    Doctor doctor = new Doctor(person);
    return personDAO.merge(doctor);
}

sorry guys,first time here.

Here´s the code above:

    private Person getDoctor(Person person) {
    //Person already a doctor ==> OK 
       if (person instanceof Doctor) { 
            return person; 
    }


     //Transient Person ==> //Transient Doctor OK
        if (person == null) {
         return new Doctor(); 
        }
    //Creates a Doctor from the person (only setting id...), and merges it ==> fails as the id changes. 
    Doctor doctor = new Doctor(person);
    return personDAO.merge(doctor); 
    }


   @Inheritance(strategy = InheritanceType.JOINED)
   @Entity
   public class Person{
   }

   @Entity
   public class Doctor extends Person{
      public Doctor(Person person) {
        if (person != null) {
            this.setId(person.getId());
        }
    }
   }
4

1 に答える 1

5

リンクした質問と同じように、答えは「Hibernate APIを使用してこれを行うことはできません」です。

その理由は実に明確です。Hibernate は永続性を可能な限り透過的にすることを目的としているため、通常の Java オブジェクトでは実行できないことを永続オブジェクトで実行することはできません。(プレーンな Java で)のインスタンスを作成するとPerson、それは常にPerson. になることは決してありませんDoctor。できる最善の方法は、インスタンスを作成し、の属性をそれにDoctorコピーすることです。Person

ただし、プレーンな Java とは異なり、Hibernate を使用すると、チートして目的を達成できます :-) が、ネイティブ SQL を介して実行する必要があります。メソッドでは、次のことを行う必要があります。

  1. セッションPersonからインスタンスを削除します (該当する場合は第 2 レベルのキャッシュも)
  2. 一致する ID (Personインスタンスから取得) を持つ行をDoctorsテーブルに挿入します。それはネイティブSQLとして実行する必要がある部分ですが、名前付きクエリとして定義し、上記のIDをパラメーターとして設定できます。プロパティに制約がある場合は、Doctor挿入する値がそれらを満たすことを確認する必要があることに注意してください。
  3. Personインスタンスのリロード- としてロードされDoctorます。
于 2009-08-30T18:00:06.910 に答える