2010-12-01 11 views
2

Ich habe eine Vererbungsstruktur mit Klassen, sagen wir Parent (als Root-Klasse) und Child als Unterklasse.JPA 2.0: TYPE Ausdruck Ausnahme

Also mit JPA 2.0 nein, ich kann mit

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

Dies ist nur die übergeordnete Klasse wählt nur Einträge von Eltern zurückkehren sollte und nicht auch die Einträge des Kindes.

Aber mit meinem Eclipse 2.1.1 und MySQL auf Glassfish v3, ich folgende Fehlermeldung immer erhalten:

"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". 

Zusätzlich definiere ich kein ORM-Mapping von Hand. Dies alles geschieht automatisch bei der Bereitstellung, denke ich.

Gibt es etwas, das ich meiner Parent/Child-Klasse (eine Annotation, d. H.) Hinzufügen muss, um die Vererbungsstruktur zu deklarieren? (Aber ich denke, das ist nicht notwendig sein sollte, weil das Erbe von Java deklariert ist, oder?)

EDIT:
Ein wichtiger Aspekt, den ich habe, ist nicht erwähnt, dass ich das bin mit Vererbungsmethode "TABLE_PER_CLASS".

+0

http://www.oracle.com/technetwork/articles/marx-jpa-087268.html Dieser Link ist in Thema 'Verwendung Tragbares Inheritance Mapping Strategies' erwähnt, dass' Selbst wenn Ihre JPA-Provider tun Implementieren Sie die optionale Vererbungsmappingstrategie "Tabelle pro konkrete Klasse", vermeiden Sie dies am besten, wenn Sie die JPA-Provider-Portabilität benötigen. "und hat die Einzelvererbung bevorzugt. – Ramsharan

Antwort

4

Vergiss was ich vorher gesagt habe. Dies wird für SINGLE_TABLE Strategie arbeiten:

@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(); 
} 

Die Datenbank (Ich bin mit Oracle) DDL sieht wie folgt aus:

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") 
); 

Nun sagten Sie, dass Sie versuchen, TABLE_PER_CLASS Strategie zu verwenden. Ich kann Ihnen dort nicht helfen, da die Spezifikation JPA 2.0 besagt, dass Verkäufer nicht erforderlich sind, es zu unterstützen. Ihre Implementierung unterstützt sie möglicherweise nicht ordnungsgemäß über die JPA-Schnittstellen.

0

die Lösung von Jum Tough funktioniert nicht für mich. Das Problem ist jedoch nur in Kombination mit der Vererbungsmethode "TABLE_PER_CLASS" verfügbar. Bei allen anderen Vererbungsstrategien funktioniert der Typ-Ausdruck gut.

Ich denke, das ist ein Fehler in EclipseLink, weil ich nichts in den JPA 2-Spezifikationen finden kann, die Explicity excludes besagt, dass der Typ Ausdruck nicht mit TABLE_PER_CLASS funktioniert.

Gerry

Verwandte Themen