0

以下に説明するように、Java EE JPA マッピングの問題が発生しています。

1) 使用されているテクノロジは休止状態 (v?? おそらく 2.9 以上) と oracle 11G です。

2) DB アーキテクトは、次のような非常に一般的な DB 構造を強制しています。

    COURSE        STUDENT_COURSES           STUDENT_DETAILS
    ------        ---------------           -------
    CR_PK (PK)    ST_ID (PK_1, FK_1)        ST_ID (PK) 
                  CR_ID (PK_2, FK_2)        FIRST_NAME
                  ROLE                      LAST_NAME
                                            IS_HAZED
                                            NUM_YEARS
                                            PRESENDENT_IND
                                            DRIVER_LICENSE_NO

3) Java EE アーキテクトは、次のようなクラス階層を強制しています。

    Interface StudentService {
       Student saveStudent(Student student);
       Student getStudent(StudentId id);
       void removeStudent(Student student);
       Set<RookieStudent> getRookies(int courseId);
       Set<SinorStudent> getSeniors(int courseId);
       JuniorStudent getStudentBodyPresedent(int courseId) (the result can be a Junior or Senior)

上記のビジネス サービス インターフェイスを実装する任意のアプローチを使用することが期待されます。そのインターフェイスは、UI モックアップがすでにビジネスによって承認されているプレゼンテーション レイヤーを最も効率的にサポートします。残りの必要なクラス階層は次のとおりです。

    Class StudentId 
       int studentId;
       int courseId;

    Class Student
       @embededId
       StudentId id

       String role;

       String first_name;
       String last_name;
       int num_years;

    Class RookieStudent extends Student
       boolean isHazed;                      

    Class JuniorStudent extends Student
       Boolean isPresendent;               

    Class SeniorStudent extends JuniorStudent
       int age;
       String driverLicenseNumber; 

4) 学生とサブクラスの詳細の大部分は、STUDENT_DETAILS テーブルから取得する必要があります。ROLE の値に応じて、クラスはそのテーブルから追加の属性を持ちます。たとえば、ROLE = 'S' の場合、driverLicenseNumber には STUDENT_DETAILS.DRIVER_LICENSE_NO の値が取り込まれます。

このモデルに対してさまざまなマッピングを試みましたが、Hibernate のエンティティ マネージャーはマッピングについて警告するか、間違った結果を生成します。JPAを使用してこのモデルをマップする方法はありますか? セカンダリ テーブルを使用して「階層ごとに 1 つのテーブル」アプローチを試みましたが、作成された Oracle クエリは完全に間違っています。ビジネス インターフェイスを使用して中学生を取得するために生成されるクエリは、次のようになります。

 SELECT c.course_id,
        c.student_id,
        d.first_name,
        d.last_name,
        c.role,
        d.num_years,
        d.presendent_ind,
   FROM student_courses c
        left outer join student_details d
             WITH c.course_id = d.student_id
  WHERE c.role = 'J' 

正しいクエリを記述する方法は簡単にわかりますが、Hibernate は何を求めているのかを理解するのに苦労しています。可能であれば、アノテーション構成を使用することをお勧めします。

4

1 に答える 1

0

JPAを無視すると、あなたがやろうとしていることはJavaでは意味がありません。生徒が別のクラスに行く場合、おそらく新しいクラスでの生徒の役割は異なる可能性があります。ジュニアはシニアになる可能性があります。役割の変更を Java オブジェクトで切り替えるだけでは不十分です。まったく新しい学生インスタンスを作成する必要があります。JB が提案したように、各テーブルをエンティティにします。次に、student_course エンティティをラッパーとして使用して、そのクラスでの学生の役割に適合する Student の属性にアクセスできます。JuniorRole タイプは、JuniorStudent に存在することを意図したフィールドのみを公開します。

Role クラスは、コースへの OneToOne と Studentdetails への OneToOne のみを含む単一のテーブル継承を使用し、ロールを型識別子として使用します。アクセサー メソッドは代わりに StudentDetails にアクセスし、新しい Role を作成すると、既存の studentDetails を再利用できます。そのため、student_details テーブルのエントリを複製することなく、複数のコースで同じ学生を異なるロールで登録できます。

于 2013-07-18T15:33:57.450 に答える