Pregunta

Tengo una estructura de herencia con las clases, digamos que los padres (como la clase raíz) y el niño como la subclase.

Así que con JPA 2.0 no lo puede seleccionar sólo la clase de padres utilizando

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

Esto sólo debería devolver las entradas de los padres y no también las entradas de niño.

Pero con mi EclipseLink 2.1.1 y MySQL en GlassFish v3, siempre me sale el siguiente error:

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

Además, defino no ORM-mapeo con la mano. Todo esto se hace de forma automática en el despliegue, creo.

¿Hay algo que tengo que añadir a mi padre / Child-Pugh (es decir, una anotación) para declarar la estructura de herencia? (Pero creo que esto no debería ser necesario, debido a que la herencia es declarado por Java, ¿verdad?)

EDIT:
Un aspecto importante que he no se menciona es que estoy usando el método de la herencia "TABLE_PER_CLASS".

¿Fue útil?

Solución

Olvida lo que dije antes. Esto funcionará para la estrategia 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();
}

La base de datos (estoy usando Oracle) miradas DDL como esta:

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

Ahora usted dice que usted está tratando de utilizar la estrategia TABLE_PER_CLASS. No te puedo ayudar, ya que la especificación JPA 2.0 dice que los vendedores no están obligados a apoyarla . Su aplicación puede no soportar adecuadamente a través de las interfaces de la APP.

Otros consejos

la solución por Jum duro no funciona para mí. Pero el problema sólo está disponible en combinación con el método de la herencia "TABLE_PER_CLASS" con todas las otras estrategias de herencia la expresión de tipo funciona muy bien.

creo que esto es un error en EclipseLink, porque no puedo encontrar nada en las APP 2 especificaciones que excluye explícitamente dice que la expresión de tipo no funciona con TABLE_PER_CLASS.

Gerry

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top