Polymorphic CriteriaQuery没有反比关系 [英] Polymorphic CriteriaQuery without inverse relationship
问题描述
我有以下EJB结构。不要怀疑 Animal
和 Inventory
,这些类只是为了以简化的方式演示结构(更新:我修改了类名以构建一个更好理解的例子。 IdTag
的另一个实现可能是 BarcodeId
)。请注意, IdTag
与 Animal
或库存$ c $之间没有反比关系c>,让我们假设
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屋!