JPA 2.0 / Hibernate:找不到超类型

3
我有一个使用JSF的web应用程序,当我尝试查询使用Hibernate映射的实体时会抛出异常(参见下文)。我做错了什么?还是Hibernate中有Bug?我该如何解决?谢谢你的帮助 :)
以下是相关的类:
基类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类还有unitlistIndex属性,其getter和setter方法的签名相同。

现在,我想使用LazyDataModel<ShipmentAction>显示一个h:dataTable。数据模型的实现使用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();

当前使用em.createQuery(...)创建TypedQuery时,会抛出异常:

[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 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

我找到了解决问题的方法。我通过使用@EmbeddedId而不是两个@Id注释来更改依赖类ShipmentAction的映射。如果您有兴趣,这里是更新后的类(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还有一个小改变:不知道为什么,ShipmentUnit.getActions()中的@javax.persistence.OrderBy注释必须替换为@org.hibernate.annotations.OrderBy


我需要这个。然而,当我切换到嵌入式键时,我还需要在我的JpaRepository方法上注释@Query("select r from UserRel r where r.key.user1Id=?1") public Iterable<UserRel> findByUser1Id(long id1); - Spencer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接