JPA 2.0 / Hibernate: супертип не найден - PullRequest
3 голосов
/ 07 февраля 2012

У меня есть веб-приложение JSF, которое выдает исключение (см. Ниже), когда я пытаюсь запросить объекты, сопоставленные с Hibernate. Что я делаю неправильно? Или это ошибка в спящем режиме? Как я могу это исправить? Спасибо за вашу помощь :)

Вот соответствующие классы:

Базовый класс ShipmentUnit с некоторыми подклассами:

@Entity
@Table(name = "tat_shipment_unit")
@Inheritance(strategy = SINGLE_TABLE)
@DiscriminatorColumn(name = "unit_type", discriminatorType = CHAR, length = 1)
@DiscriminatorValue("_")
public abstract class ShipmentUnit implements Serializable {
    private Long id;
    private List<ShipmentAction> actions;

    @Id @GeneratedValue
    public Long getId() { return id; }  // and corresponding setter

    @OneToMany(mappedBy = "unit")
    @OrderBy("listIndex")
    public List<ShipmentAction> getActions() { return actions; }  // and setter

    // hashCode, equals etc.
}

Класс ShipmentAction:

@Entity
@Table(name = "tat_shipment_action")
@IdClass(ShipmentActionID.class)
public class ShipmentAction implements Serializable {
    private ShipmentUnit unit;
    private int listIndex;

    @Id @ManyToOne @NotNull
    public ShipmentUnit getUnit() { return unit; }  // and setter

    @Id @Column(name = "list_index", nullable = false)
    public int getListIndex() { return listIndex; } // and setter
}

Класс ShipmentActionID также имеет свойства unit и listIndex с одинаковыми сигнатурами в методах получения и установки.

Теперь я хочу отобразить h:dataTable с LazyDataModel<ShipmentAction>. Реализация модели данных использует Criteria API для (1) подсчета и (2) запроса для этих объектов действия отправки, например:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Number> query = cb.createQuery(Number.class);
Root<ShipmentAction> root = query.from(ShipmentAction.class);
Predicate predicates = ...
int total = em.createQuery(
    query.select(cb.count(root).where(predicates)
).getSingleResult().intValue();

На данный момент TypedQuery должен быть создан с em.createQuery(...), создается исключение:

[SEVERE] Error Rendering View[/tat/report/actions.xhtml]: java.lang.IllegalStateException: No supertype found
at org.hibernate.ejb.metamodel.AbstractIdentifiableType.requireSupertype(AbstractIdentifiableType.java:85)
at org.hibernate.ejb.metamodel.AbstractIdentifiableType.getIdType(AbstractIdentifiableType.java:173)
at org.hibernate.ejb.criteria.expression.function.AggregationFunction$COUNT.renderArguments(AggregationFunction.java:110)
at org.hibernate.ejb.criteria.expression.function.ParameterizedFunctionExpression.render(ParameterizedFunctionExpression.java:94)
at org.hibernate.ejb.criteria.expression.function.BasicFunctionExpression.renderProjection(BasicFunctionExpression.java:71)
at org.hibernate.ejb.criteria.QueryStructure.render(QueryStructure.java:250)
at org.hibernate.ejb.criteria.CriteriaQueryImpl.render(CriteriaQueryImpl.java:338)
at org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:223)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:619)

Я использую Hibernate Version 4.0.0.Final, работающий на JBoss AS 7.

        <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.spec.javax.ejb</groupId>
        <artifactId>jboss-ejb-api_3.1_spec</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.spec.javax.annotation</groupId>
        <artifactId>jboss-annotations-api_1.1_spec</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.enterprise</groupId>
        <artifactId>cdi-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.0.0.Final</version>
        <scope>provided</scope>
    </dependency>

1 Ответ

4 голосов
/ 08 февраля 2012

Я нашел решение своей проблемы. Я изменил отображение зависимого класса ShipmentAction, используя @EmbeddedId вместо двух @Id аннотаций. Если вам интересно, вот обновленный класс (отображение класса ShipmentUnit не изменилось 1 )

@Entity
@Table(name = "tat_shipment_action")
public class ShipmentAction implements Serializable {
    private @EmbeddedId Key id;
    private @MapsId("unit_id") @ManyToOne ShipmentUnit unit;

    public ShipmentAction() {
        id = new Key();
    }

    public ShipmentUnit getUnit() { return unit; }  // and setter

    public int getListIndex() {
        return id.list_index;
    }

    public void setListIndex(int index) {
        id.list_index = index;
    }

    @Embeddable
    public static class Key implements Serializable {
        public long unit_id;
        public int list_index;
        // hashCode() and equals()
    }
}

Хорошо, похоже, это работает, и моему LazyDataModel<ShipmentAction> теперь нравится: -)
Но единственное, что странно, это то, что это работает только с аннотациями JPA на полях, Hibernate больше не может справляться с этими аннотациями на методах getter (по крайней мере, на классах, затронутых моим изменением). Есть мысли по этому поводу?

1 Еще одно небольшое изменение: аннотацию @javax.persistence.OrderBy в ShipmentUnit.getActions() по любой причине пришлось заменить на @org.hibernate.annotations.OrderBy.

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