2012-02-07 2 views
3

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

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

Базовый класс 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>. Реализация модели данных использует критерии 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> 

ответ

4

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

@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 (по крайней мере, на классах, затронутых моим изменением). Любые мысли об этом?

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

+0

Мне это нужно. Однако, когда я переключился на встроенный ключ, мне также нужно было аннотировать мои методы JpaRepository с помощью '@Query (« выберите r из UserRel r, где r.key.user1Id =? 1 ») \t public Iterable findByUser1Id (long id1) ; ' – Spencer

Смежные вопросы