2010-12-01 10 views
2

私はクラスに継承構造を持っています.Parent(ルートクラスとして)とChildをサブクラスとしましょう。 JPA 2.0:TYPE式の例外

だからJPA 2.0で何私は、親のエントリと子のないものエントリを返す必要があり

SELECT p FROM Parent p WHERE TYPE(p) = Parent 

これを使用することによってのみ、親クラスを選択することはできません。

しかし、私のEclipseLink 2.1.1とMySQLでのGlassFish v3の上、私は常に次のエラーを取得する:

さらに
"Invalid Type Expression on [my.domain.Parent]. The class 
does not have a descriptor, or a descriptor that does not use 
inheritance or uses a ClassExctractor for inheritance". 

、私は手で何のORMマッピングを定義していません。これはすべて展開時に自動的に行われます。

継承構造を宣言するために、親/子クラス(注釈)に追加する必要があるものはありますか? (しかし、私はそれは、継承はJavaで宣言されているため、これは、必要ではないはずだと思う?)

EDIT:
私は言及しなかったてきた1つの重要な側面は、私が使用しているということです継承メソッド "TABLE_PER_CLASS"。

+0

このリンクは '使用ポータブル継承マッピングStrategies'あなたのJPAプロバイダがない場合でも、'そのトピックに言及しているhttp://www.oracle.com/technetwork/articles/marx-jpa-087268.htmlオプションの "表コンクリートクラス"の継承マッピング戦略を実装すると、JPAプロバイダの移植性が必要な場合はこれを避けるのが最善です.'そして単一の継承を使用することが好ましい。 – Ramsharan

答えて

4

前に言ったことを忘れてしまった。これは、SINGLE_TABLE戦略のために動作します:

@Entity 
@Table(name="PERSON") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="GENDER", discriminatorType=DiscriminatorType.STRING, length=6) 
public abstract class Person implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @SequenceGenerator(name="PERSON_PERSONID_GENERATOR", sequenceName="PERSON_ID_SEQ") 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="PERSON_PERSONID_GENERATOR") 
    @Column(name="PERSON_ID", updatable=false, unique=true, nullable=false, precision=22) 
    private long personId; 

    @Column(nullable=false, length=32) 
    private String surname; 

    @Column(name="GIVEN_NAME", nullable=false, length=32) 
    private String givenName; 

    // ... 
} 


@Entity 
@DiscriminatorValue("FEMALE") 
public class Daughter extends Person implements Serializable { 

    @Column(name="NUMBER_OF_DOLLS", precision=22) 
    private int numberOfDolls; 

    // ... 
} 


@Entity 
@DiscriminatorValue("MALE") 
public class Son extends Person implements Serializable { 

    @Column(name="NUMBER_OF_TOY_CARS", precision=22) 
    private Integer numberOfToyCars; 

    // ... 
} 


// JUnit test method 
public void testInheritance() { 
    EntityManager em = createNewEntityManagerInstance(); 

    EntityTransaction tx = em.getTransaction(); 
    tx.begin(); 
    Daughter d = new Daughter(); 
    d.setGivenName("Sue"); 
    d.setSurname("Smith"); 
    d.setNumberOfDolls(5); 
    em.persist(d); 
    Son s = new Son(); 
    s.setGivenName("Joe"); 
    s.setSurname("Smith"); 
    s.setNumberOfToyCars(8); 
    em.persist(s); 
    tx.commit(); 

    Query q; 
    List<?> personList; 
    Person p; 

    q = em.createQuery("SELECT p FROM Person p WHERE TYPE(p) = Daughter"); 
    personList = q.getResultList(); 
    assertEquals(1, personList.size()); 
    p = (Person)personList.get(0); 
    System.out.println(
     "This Daughter is: " + p.getGivenName() + " " + p.getSurname()); 
    q = em.createQuery("SELECT p FROM Person p WHERE TYPE(p) = Son"); 
    personList = q.getResultList(); 
    assertEquals(1, personList.size()); 
    p = (Person)personList.get(0); 
    System.out.println(
     "This Son is: " + p.getGivenName() + " " + p.getSurname()); 
    q = em.createQuery("SELECT p FROM Person p"); 
    personList = q.getResultList(); 
    assertEquals(2, personList.size()); 
    for (Object o : personList) { 
     assertTrue(o instanceof Person); 
     p = (Person)o; 
     System.out.println(
      "This person is: " + p.getGivenName() + " " + p.getSurname()); 
    } 
    em.close(); 
} 

データベース(私は、Oracleを使用しています)DDLは次のようになります。

CREATE TABLE "DEV"."PERSON" 
( 
"PERSON_ID" NUMBER NOT NULL ENABLE, 
"GIVEN_NAME" VARCHAR2(32 BYTE) NOT NULL ENABLE, 
"SURNAME" VARCHAR2(32 BYTE) NOT NULL ENABLE, 
"GENDER" VARCHAR2(6 BYTE) NOT NULL ENABLE, 
"NUMBER_OF_DOLLS" NUMBER, 
"NUMBER_OF_TOY_CARS" NUMBER, 
CONSTRAINT "PERSON_PK" PRIMARY KEY ("PERSON_ID") 
); 

あなたがTABLE_PER_CLASS戦略を使用しようとしていると述べました。 JPA 2.0仕様では、ベンダーはそれをサポートする必要がないと言っていますので、をお手伝いすることはできません。実装では、JPAインタフェースを使用してその実装を適切にサポートしていない可能性があります。

0

Jum Toughによる解決策は私にとっては役に立たない。しかし、この問題は、継承メソッド "TABLE_PER_CLASS"との組み合わせでしか利用できません。他のすべての継承ストラテジでは、型式がうまく動作します。

JPA 2仕様では明示的に除外されているため、タイプ表現がTABLE_PER_CLASSで機能しないとは言いませんので、これはEclipseLinkのバグだと思います。

ゲリー