JPA条件构建器联接图 [英] jpa criteriabuilder join maps
问题描述
我有以下条件构建器查询
I have the following criteria builder query
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Object> critQuery = cb.createQuery();
Root<Role> role = critQuery.from(Role.class);
//create a join between role and permission
MapJoin<Role,String,Permission> perm = role.joinMap("permissions");
critQuery.multiselect(role.get("label"), perm.key(), perm.value());
//this line throws NPE
Query query = em.createQuery(critQuery);
最后一行抛出空指针异常.
The last line throws a null pointer exception.
java.lang.NullPointerException
at org.hibernate.ejb.criteria.path.AbstractPathImpl.prepareAlias(AbstractPathImpl.java:246)
at org.hibernate.ejb.criteria.path.AbstractPathImpl.render(AbstractPathImpl.java:253)
at org.hibernate.ejb.criteria.path.AbstractPathImpl.renderProjection(AbstractPathImpl.java:261)
推荐答案
我有完全相同的问题.经过数小时的处理,调试了Hibernate源代码,并反复检查了书本和JPA 2.0规范中的示例之后,我决定尝试在EclipseLink中进行尝试.
I have exactly the same problem. After hours of dealing with the issue, and after debugging the Hibernate source code, and after checking over and over again the examples in books and in the JPA 2.0 Specification, I decided to give it a try in EclipseLink.
因此,我创建了一个非常简单的示例:一名员工,带有一个电话号码地图,其中的关键是电话的类型(家庭,办公室,移动电话),而值是电话号码.
So, I created a very simple example: an employee with a map of phone numbers, where the key is the type of phone (home, office, mobile) and the value was the phone number.
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name="emp_phone")
@MapKeyColumn(name="phone_type")
@Column(name="phone_num")
private Map<String, String> phoneNumbers;
我可以验证它可以与EclipseLink 2.1和OpenJPA 2.1.0完美配合,但是在Hibernate 3.5.3、3.6.1.,3.6.3中会失败
I could verify that this works perfectly with EclipseLink 2.1 and OpenJPA 2.1.0, but it fails in Hibernate 3.5.3, 3.6.1., 3.6.3
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> criteria = builder.createQuery(Employee.class);
Root<Employee> employeeRoot = criteria.from(Employee.class);
criteria.select(employeeRoot);
MapJoin<Employee, String, String> phoneRoot = employeeRoot.joinMap("phoneNumbers");
criteria.where(builder.equal(phoneRoot.key(), "HOME"));
System.out.println(entityManager.createQuery(criteria).getResultList());
我认为,如果Criteria API失败了,也许我可以使用命名查询来做到这一点.有趣的是,Hibernate不支持KEY,VALUE或ENTRY关键字,因此查询被证明格式错误.
I thought, well if Criteria API fails, perhaps I can do it with a named query. Interestingly, Hibernate does not support the KEY, VALUE or ENTRY keywords, and therefore queries proved to be malformed.
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5396
这是运行:
String query = "SELECT e FROM Employee e JOIN e.phoneNumbers p WHERE KEY(p) IN ('HOME')";
System.out.println(entityManager.createQuery(query, Employee.class).getResultList());
在休眠状态下,它会生成以下SQL查询:
In hibernate it generates the following SQL query:
select
employee0_.id as id0_,
employee0_.name as name0_
from
Employee employee0_
inner join
emp_phone phonenumbe1_
on employee0_.id=phonenumbe1_.Employee_id
where
KEY(phonenumbe1_.phone_num) in (
'HOME'
)
显然是畸形的.
同样,在EclipseLink和OpenJPA中,此方法有效.
Again, in EclipseLink and OpenJPA this works.
因此,显然,Hibernate一定有问题.我已经在Hibernate Jira问题跟踪器中提交了一个错误
So, evidently, something must be wrong with Hibernate. I have submitted an bug in the Hibernate Jira Issue Tracker
http://opensource.atlassian.com/projects/hibernate/browse/HHH-6103
并已在Hibernate用户论坛中发布了问题
And have posted the question in the Hibernate Users Forum
https://forum.hibernate.org/viewtopic.php? f = 1& t = 1010411
这篇关于JPA条件构建器联接图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!