jpa criteriabuilder加入地图

use*_*201 5 jpa

我有以下条件构建器查询

    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);
Run Code Online (Sandbox Code Playgroud)

最后一行抛出空指针异常.

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)
Run Code Online (Sandbox Code Playgroud)

Edw*_*rzo 9

我有完全一样的问题.经过几个小时的处理,以及调试Hibernate源代码之后,经过一遍又一遍地检查书籍和JPA 2.0规范中的示例后,我决定尝试使用EclipseLink.

所以,我创建了一个非常简单的例子:一个带有电话号码地图的员工,其中键是电话类型(家庭,办公室,移动电话),价值是电话号码.

@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name="emp_phone")
@MapKeyColumn(name="phone_type")
@Column(name="phone_num")
private Map<String, String> phoneNumbers;
Run Code Online (Sandbox Code Playgroud)

我可以验证这与EclipseLink 2.1和OpenJPA 2.1.0完美配合,但在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());
Run Code Online (Sandbox Code Playgroud)

我想,如果Criteria API失败,也许我可以用命名查询来做.有趣的是,Hibernate不支持KEY,VALUE或ENTRY关键字,因此查询被证​​明是格式错误的.

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());
Run Code Online (Sandbox Code Playgroud)

在hibernate中,它会生成以下SQL查询:

   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'
        )
Run Code Online (Sandbox Code Playgroud)

这显然是畸形的.

再次,在EclipseLink和OpenJPA中这是有效的.

所以,显然,Hibernate必定存在问题.我在Hibernate Jira Issue Tracker中提交了一个错误

http://opensource.atlassian.com/projects/hibernate/browse/HHH-6103

并在Hibernate用户论坛中发布了这个问题

https://forum.hibernate.org/viewtopic.php?f=1&t=1010411