JPA - 标准 API 和 EmbeddedId [英] JPA - Criteria API and EmbeddedId
问题描述
我想使用条件进行以下查询.我有一个 Entity 定义了 EmbeddedId:
@Entity@Table(name="TB_INTERFASES")公共类接口实现可序列化{@EmbeddedId私有InterfaseId id;}@Embeddable公共类 InterfaseId 实现了 Serializable {@Column(名称=CLASE")私有字符串类;}
我想做的标准查询是:
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();CriteriaQuery标准查询 = 标准构建器.createQuery(Interfase.class);根<接口>entity = criteriaQuery.from(Interfase.class);条件查询.where(criteriaBuilder.equal(entity.get("class"), "Clase"),);
但这会抛出一个 IllegalArgumentException:
java.lang.IllegalArgumentException:不是托管类型:类 InterfaseId
我也试过这个查询:
Rootentity = criteriaQuery.from(Interfase.class);条件查询.where(criteriaBuilder.equal(entity.get("id").get("clase"), "Clase"),);
还有这个...
Rootentity = criteriaQuery.from(Interfase.class);条件查询.where(criteriaBuilder.equal(entity.get("id.clase", "Clase"),);
没有运气.所以我的问题是,当我的类使用 Embedded 和 EmbeddedId 注释时,如何使用条件进行查询?
谢谢!毛罗.
您需要使用路径导航来访问 Embeddable
的属性.这是 JPA 2.0 规范中的一个示例(使用静态元模型):
6.5.5 路径导航
...
在下面的例子中,ContactInfo
是一个可嵌入的类由一个地址和一组电话.Phone
是一个实体.
CriteriaQueryq = cb.createQuery(Vendor.class);根<员工>emp = q.from(Employee.class);加入电话 =emp.join(Employee_.contactInfo).join(ContactInfo_.phones);q.where(cb.equal(emp.get(Employee_.contactInfo).get(ContactInfo_.address).get(Address_.zipcode), "95054")).select(phone.get(Phone_.vendor));
以下 Java 持久化查询语言查询等价:
SELECT p.vendorFROM Employee e JOIN e.contactInfo.phones pWHERE e.contactInfo.address.zipcode = '95054'
所以在你的情况下,我认为你需要这样的东西:
criteriaBuilder.equal(entity.get("id").get("clase"), "Referencia 111")
参考资料
- JPA 2.0 规范
- 第 6.5.5 节路径导航"
更新:我已经使用 Hibernate EntityManager 3.5.6 和以下查询测试了提供的实体:
CriteriaBuilder builder = em.getCriteriaBuilder();CriteriaQuery标准 = builder.createQuery(Interfase.class);根<接口>interfaseRoot = criteria.from(Interfase.class);标准.选择(interfaceRoot);标准.where(builder.equal(interfaseRoot.get("id").get("class"),"参考文献 111"));列表<接口>interfases = em.createQuery(criteria).getResultList();
运行良好并生成以下 SQL:
<前>17:20:26.893 [主] 调试 org.hibernate.SQL -选择interfase0_.CLASE 作为 CLASE31_从TB_INTERFASES 接口0_在哪里接口0_.CLASE=?17:20:26.895 [main] TRACE org.hibernate.type.StringType - 将Referencia 111"绑定到参数:1按预期工作.
I want to use criteria to make the following query. I have an Entity with EmbeddedId defined:
@Entity
@Table(name="TB_INTERFASES")
public class Interfase implements Serializable {
@EmbeddedId
private InterfaseId id;
}
@Embeddable
public class InterfaseId implements Serializable {
@Column(name="CLASE")
private String clase;
}
And the criteria query that i am trying to do is:
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Interfase> criteriaQuery = criteriaBuilder.createQuery(Interfase.class);
Root<Interfase> entity = criteriaQuery.from(Interfase.class);
criteriaQuery.where(
criteriaBuilder.equal(entity.get("clase"), "Clase"),
);
But this is throwing an IllegalArgumentException:
java.lang.IllegalArgumentException: Not an managed type: class InterfaseId
i've tried with this queries too:
Root<Interfase> entity = criteriaQuery.from(Interfase.class);
criteriaQuery.where(
criteriaBuilder.equal(entity.get("id").get("clase"), "Clase"),
);
and this one too...
Root<Interfase> entity = criteriaQuery.from(Interfase.class);
criteriaQuery.where(
criteriaBuilder.equal(entity.get("id.clase", "Clase"),
);
with no luck. So my question is how can i make a query with criteria when my classes are using Embedded and EmbeddedId annotations?
Thanks!. Mauro.
You need to use path navigation to access the attribute(s) of the Embeddable
. Here is an example from the JPA 2.0 specification (using the static metamodel):
6.5.5 Path Navigation
...
In the following example,
ContactInfo
is an embeddable class consisting of an address and set of phones.Phone
is an entity.CriteriaQuery<Vendor> q = cb.createQuery(Vendor.class); Root<Employee> emp = q.from(Employee.class); Join<ContactInfo, Phone> phone = emp.join(Employee_.contactInfo).join(ContactInfo_.phones); q.where(cb.equal(emp.get(Employee_.contactInfo) .get(ContactInfo_.address) .get(Address_.zipcode), "95054")) .select(phone.get(Phone_.vendor));
The following Java Persistence query language query is equivalent:
SELECT p.vendor FROM Employee e JOIN e.contactInfo.phones p WHERE e.contactInfo.address.zipcode = '95054'
So in your case, I think you'll need something like this:
criteriaBuilder.equal(entity.get("id").get("clase"), "Referencia 111")
References
- JPA 2.0 Specification
- Section 6.5.5 "Path Navigation"
Update: I've tested the provided entities with Hibernate EntityManager 3.5.6 and the following query:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Interfase> criteria = builder.createQuery(Interfase.class);
Root<Interfase> interfaseRoot = criteria.from(Interfase.class);
criteria.select(interfaseRoot);
criteria.where(builder.equal(interfaseRoot.get("id").get("clase"),
"Referencia 111"));
List<Interfase> interfases = em.createQuery(criteria).getResultList();
runs fine and generates the following SQL:
17:20:26.893 [main] DEBUG org.hibernate.SQL - select interfase0_.CLASE as CLASE31_ from TB_INTERFASES interfase0_ where interfase0_.CLASE=? 17:20:26.895 [main] TRACE org.hibernate.type.StringType - binding 'Referencia 111' to parameter: 1
Works as expected.
这篇关于JPA - 标准 API 和 EmbeddedId的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!