HIBERNATE - JPA2 - H2 - 按键查询@ElementCollections HashMap

标签 hibernate hashmap filtering jpa-2.0 h2

我正在使用 hibernate-entitymanager 3.6.4.Final 和 h2 数据库 1.3.155

我正在使用 H2Dialect。

我在按 @ElementCollection 中的元素过滤记录时遇到问题。 这是我的实体

@Entity
public class Item {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @MapKeyColumn(name="name", length=50)
  @Column(name="value", length=100)
  protected Map<String, String> attributes;
  /*  etc.  */
}

这是我的查询:

Item item = em.createQuery("FROM Item i JOIN i.attributes a WHERE KEY(a)='myAttrName'").getSingleResult();

这是错误消息:

4971 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 90022, SQLState: 90022
4971 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Function "KEY" not found; SQL statement:
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute query

这很奇怪,因为函数 KEY() 和 VALUE() 在文档 here 中可用。

我是否缺少一些配置? 有什么想法吗?

提前致谢

最佳答案

我也有同样的问题。经过几个小时的处理这个问题,调试 Hibernate 源代码,并一遍又一遍地检查书籍和 JPA 2.0 规范中的示例后,我决定在 EclipseLink 中尝试一下。

因此,我创建了一个非常简单的示例:一名员工拥有电话号码 map ,其中键是电话类型(家庭、办公室、手机),值是电话号码。

@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 中失败

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 关键字,因此查询被证​​明是格式错误的。

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());

在 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'
        )

这显然是畸形的。

同样,在 EclipseLink 和 OpenJPA 中,这是可行的。

所以,显然,Hibernate 一定出了问题。我已在 Hibernate Jira 问题跟踪器中提交了一个错误

https://hibernate.atlassian.net/browse/HHH-6103

并已在 Hibernate 用户论坛中发布了该问题

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

最后,我必须使用包含与 map 相同条目的可嵌入对象集合来解决问题。我被迫在可嵌入中实现 equals 和 hasHCode 以满足相同的行为。

关于HIBERNATE - JPA2 - H2 - 按键查询@ElementCollections HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6246735/

相关文章:

mysql - 无法让外部 MySQL 服务器与 Java Web 应用程序 + Hibernate 一起工作。 (无法构建 EntityManagerFactory)

java - 在 Oracle 和 Hibernate 中使用 ID 列序列会创建奇怪的(负)值

algorithm - Hashmap hashcode到内表索引的转换

dart - 我如何在 Flutter DropDown 按钮中搜索

reactjs - 为什么在其( react 表)数据更改时会重置 react 表分页和过滤器?

java - 让一个简单的 envers 示例工作起来很困难 : problem #34

mysql - 删除表中的一行 mysql hiberhate

java - 如何转换 getter 的返回值

c++ - 在 STL Hash_map 中查找键

php - 搜索过滤器,我应该在客户端还是服务器端进行?