gpt4 book ai didi

java - 没有反向关系的多态 CriteriaQuery

转载 作者:太空狗 更新时间:2023-10-29 22:57:28 25 4
gpt4 key购买 nike

我有以下 EJB 结构。不要好奇AnimalInventory,这些类在这里只是为了简化结构演示(更新:我修改了类名来构造一个更好理解的示例。IdTag 的另一个实现可能是 BarcodeId)。请注意,从 IdTagAnimalInventory 没有反比关系,我们假设 RfidTag.code 是独特的。我读了Retrieving Polymorphic Hibernate Objects Using a Criteria QueryHibernate polymorphic query但这些讨论似乎并没有回答我的问题。

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 查询 AnimalInventory,例如 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 -> RfidTagAnimal 只知道 IdTag 有关而不是 RfidTag.code。这样的查询可能吗?

最佳答案

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

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

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

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”之间形成一个“连接”(“过滤后的笛卡尔积”)。

关于java - 没有反向关系的多态 CriteriaQuery,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6427126/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com