JPA条件构建器联接图 [英] jpa criteriabuilder join maps

查看:69
本文介绍了JPA条件构建器联接图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下条件构建器查询

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆