JPA 2.0: исключение выражения TYPE - PullRequest
2 голосов
/ 01 декабря 2010

У меня есть структура наследования с классами, скажем, Parent (в качестве корневого класса) и Child в качестве подкласса.

Так что с JPA 2.0 нет, я могу выбрать только родительский класс с помощью

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

Это должно возвращать только записи Parent, а не записи child.

Но с 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 вручную. Я думаю, все это делается автоматически при развертывании.

Есть ли что-то, что я должен добавить в мой класс Parent / Child (аннотация, т. Е.), Чтобы объявить структуру наследования? (Но я думаю, что в этом нет необходимости, потому что наследование объявлено Java, не так ли?)

EDIT:
Один важный аспект, который я не упомянул, заключается в том, что я использую метод наследования "TABLE_PER_CLASS".

Ответы [ 2 ]

4 голосов
/ 02 декабря 2010

Забудь, что я сказал раньше. Это будет работать для стратегии 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 голосов
/ 02 декабря 2010

решение от Jum Tough не работает для меня. Но проблема доступна только в сочетании с методом наследования "TABLE_PER_CLASS" со всеми другими стратегиями наследования, выражение типа работает просто отлично.

Я думаю, что это ошибка в EclipseLink, потому что я не могу найти ничего в спецификациях JPA 2, исключение из которых объясняет простота, говорит, что выражение типа не работает с TABLE_PER_CLASS.

Джерри

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...