Polymorphic CriteriaQuery没有反比关系 [英] Polymorphic CriteriaQuery without inverse relationship

查看:120
本文介绍了Polymorphic CriteriaQuery没有反比关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下EJB结构。不要怀疑 Animal Inventory ,这些类只是为了以简化的方式演示结构(更新:我修改了类名以构建一个更好理解的例子。 IdTag 的另一个实现可能是 BarcodeId )。请注意, IdTag Animal 库存,让我们假设 RfidTag.code 是唯一的。我阅读使用条件查询检索多态Hibernate对象 Hibernate多态查询但这些讨论似乎没有回答我的问题。

I have the following EJB structure. Don't wonder about Animal and Inventory, these classes are only here to demonstrate the structure in a simplified way (Update: I have revised the class names to construct a better understandable example. Another implementation of IdTag might be a BarcodeId). Note that there is no inverse relationship from IdTag to Animal or Inventory, and let's assume the RfidTag.code is unique. I read Retrieving Polymorphic Hibernate Objects Using a Criteria Query and Hibernate polymorphic query but these discussions does not seem to answer my question.

public interface ItemWithIdTag
{
    IdTag getIdTag();
    void setIdTag(IdTag idTag);
}

@Entity public class Animal implements ItemWithIdTag,Serializable
{
    @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id;

    @OneToOne(cascade = CascadeType.ALL)
    private IdTag idTag;
}

@Entity public class Inventory implements ItemWithIdTag,Serializable
{
    @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id;

    @OneToOne(cascade = CascadeType.ALL)
    private IdTag idTag;
}

@Entity @Table(name = "IdTag") @Inheritance(strategy= InheritanceType.JOINED)
public class IdTag implements Serializable
{
    @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id;
    private Date created;
}

@Entity @Table(name = "RfidTag")
public class RfidTag extends IdTag implements Serializable
{
    private String code;
}

现在我要查询 Animal RfidTag.code 的c $ c>或库存,如 Animal ejb = bean。 fEntityWithRfidTag(Animal.class,myRfIdCode);

Now I want to query either Animal or Inventory for a given RfidTag.code like Animal ejb = bean.fEntityWithRfidTag(Animal.class,"myRfIdCode");

public <T extends ItemWithIdTag> T fOwner(Class<T> type, String catName)
{
    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type);
    Root<T> from = criteriaQuery.from(type);

    Path<Object> path = from.join("idTag").get("code");

    CriteriaQuery<T> select = criteriaQuery.select(from);
    select.where(criteriaBuilder.equal(path, catName));

    TypedQuery<T> q = em.createQuery(select); 
    T result = (T)q.getSingleResult();}
    return result;
}

不幸的是我得到以下错误:

Unfortuately I get the following errror:

javax.ejb.EJBException: java.lang.IllegalArgumentException:
Unable to resolve attribute [code] against path [null]

我认为这与继承有关 IdTag - > RfidTag Animal 只知道 IdTag 而不是 RfidTag.code 。这样的查询是否可能?

I assume that this is related to the inheritance IdTag -> RfidTag and Animal only knows about IdTag and not the RfidTag.code. Are queries like this possible?

推荐答案

如果您使用的是EclipseLink,解决方案很简单。修改路径条件以转换为RfIdTag:

If you are using EclipseLink, solution is simple. Modify the Path criteria to cast to RfIdTag:

Path<Object> path = ((Path) from.join("idTag").as(RfIdTag.class)).get("code");

如果您使用的是Hibernate,请将您的方法替换为:

If you are using Hibernate, replace your method with:

public static <T extends ItemWithIdTag> T fOwner(Class<T> type, String catName) {
    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type);
    Root<T> fromType = criteriaQuery.from(type);
    Root<RfIdTag> fromRfId = criteriaQuery.from(RfIdTag.class);

    Path<Object> pathCode = fromRfId.get("code");
    Path<Object> pathIdTagType = fromType.get("idTag");
    Path<Object> pathIdTagRfId = fromRfId.get("id");

    CriteriaQuery<T> select = criteriaQuery.select(fromType);
    select.where(
            criteriaBuilder.equal(pathCode, catName),
            criteriaBuilder.equal(pathIdTagType, pathIdTagRfId));

    TypedQuery<T> q = em.createQuery(select);
    return q.getSingleResult();
}

这使得加入(过滤后的笛卡儿产品)介于 T和RfIdTag。

This makes a "join" ("a filtered cartesian product") between "T" and "RfIdTag".

这篇关于Polymorphic CriteriaQuery没有反比关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆