3

Hibernate で JPA を使用して、既存のスキーマからデータを読み取ろうとしています。スキーマを変更できません。複数のサブクラスを持つ User クラスがあります。これらのサブクラスには、結合されたテーブルに格納される追加データがあるものとないものがあります。具体的な例として、次の 3 つのクラスと 2 つのテーブルを考えてみましょう。(実際には、数十のバリアントと約 12 のテーブルがあります。)

  • User共通の基本クラスです。これには、userType という名前の識別子列が含まれています。テーブルには、数値を含むUSERすべてのクラスに共通のデータが保持されます。UserUSERID
  • StandardUser追加データのない 1 つのバリアントです。
  • LoginUseron にLOGIN_USER結合されたテーブルに格納された、ユーザー名とパスワードを持つ別のバリアントです。USERUSERID

以下は OpenJPA で機能します。

@Entity
@Table(name="USER")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="USERTYPEID", discriminatorType=DiscriminatorType.INTEGER)
public class User {
    private @Id long userId;
    private String userName;
    private int userTypeId;
    ...
}

@Entity
@Table(name="USER")
@DiscriminatorValue("1")
public class StandardUser extends User {

}

@Entity
@Table(name="LOGIN_USER")
@DiscriminatorValue("2")
public class LoginUser extends User {
    private String login;
    private String password;
    ....
}

USERLOGIN_USER(左外部結合で) を結合する SQL コードを生成USERIDし、userTypeId 値が 1 か 2 かに応じて、StandardUser または LoginUser を適切に作成します。

同じコードを OpenJPA ではなく Hibernate にリンクすると、エラー メッセージが表示される

Caused by: org.hibernate.AnnotationException: Foreign key circularity dependency involving the following tables: 

エラー メッセージに一覧表示されているテーブルはありません。例外にブレークポイントを設定しましたが、「USER」と「USER」の間の「依存関係」を解決しようとしているか、そう表示されます。Hibernate バージョン 3.6 および 4.1.7 でこれを試しました。

(なぜ OpenJPA に固執しないのですか? 読み込み時のコード書き換えと JAXB との競合に関連して、そこで別の問題を抱えています。)

4

1 に答える 1

1

関連する質問を見るのにもっと時間を費やすべきでした。JPAアノテーションを介してクラス階層のブランチで継承戦略を変更するで提案された戦略は、私が必要とすることを行うようです。

具体的には、コードを次のように変更すると、コンパイルして実行し、単体テストに合格します。

@Entity
@Table(name="USER")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="USERTYPEID", discriminatorType=DiscriminatorType.INTEGER)
@DiscriminatorValue("1")
public class User {
    private @Id long userId;
    private String userName;
    private int userTypeId;
    ...
}

@Entity
@DiscriminatorValue("1")
public class StandardUser {
}

@Entity
@SecondaryTable(name="LOGIN_USER")
@DiscriminatorValue("2")
public class LoginUser extends User {
    @Column(table="LOGIN_USER")
    private String login;
    @Column(table="LOGIN_USER")
    private String password;
    ....
}
于 2013-03-25T21:20:00.720 に答える