无逆关系的多态 CriteriaQuery
我有以下 EJB 结构。不要怀疑 Animal
和 Inventory
,这些类只是为了以简化的方式演示结构(更新:我已经修改了类名来构造一个更好理解的示例。IdTag
的另一个实现可能是 BarcodeId
)。请注意,IdTag
与 Animal
或 Inventory
之间没有反比关系,我们假设 RfidTag.code
为独特的。我阅读了 使用条件查询检索多态 Hibernate 对象 和 Hibernate多态查询但是这些讨论似乎并没有回答我的问题。
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;
}
现在我想查询给定 RfidTag.code
的 Animal
或 Inventory
,例如 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;
}
不幸的是,我收到以下错误:
javax.ejb.EJBException: java.lang.IllegalArgumentException:
Unable to resolve attribute [code] against path [null]
我认为这与继承 IdTag
->; RfidTag
和 Animal
仅了解 IdTag
,而不了解 RfidTag.code
。这样的查询可以吗?
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;
}
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]
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您使用 EclipseLink,解决方案很简单。修改路径条件以转换为 RfIdTag:
如果您使用 Hibernate,请将您的方法替换为:
这会在“T”和“RfIdTag”之间形成“连接”(“过滤的笛卡尔积”)。
If you are using EclipseLink, solution is simple. Modify the Path criteria to cast to RfIdTag:
If you are using Hibernate, replace your method with:
This makes a "join" ("a filtered cartesian product") between "T" and "RfIdTag".