JPA 2.0 / Hibernate: супертип не найден
У меня есть веб-приложение 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 ответ
Я нашел решение своей проблемы. Я изменил отображение зависимого класса 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
для любой причины.