当前位置: 首页 > 面试题库 >

HIBERNATE-JPA2-H2-通过键查询@ElementCollections HashMap

邓韬
2023-03-14
问题内容

我正在使用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()函数

我是否缺少某些配置?任何的想法 ?

提前致谢


问题答案:

我有完全一样的问题。经过数小时的处理,调试了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;

我可以验证它是否可以与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

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



 类似资料:
  • 问题内容: 我有一个对象(BlogPost),其中包含元素(标记)的M:N集合。 如何查询对象(BlogPost)中至少一个对象的标签与使用JPA2(hibernate)的一组标签(由用户定义)中的元素匹配。 我的主要问题是,我实际上需要比较两个标签集合:-BlogPost的标签集合。-我搜索的收藏集 我尝试了一下,但是它不起作用,因为我的帖子实体具有多个标签。 那我该怎么办呢? 我的BlogPo

  • 问题内容: 问题: 1)如果我从Hibernate 4.x升级到Hibernate 5.x,我仍然可以使用“旧”条件查询还是仅使用新的 Typed JPA2条件查询?旧的是否已弃用,还是可以同时使用? 2)我是否正确理解新的类型化标准会迫使我为我拥有的 每个 实体类创建第二个类,从而使类的数量重复?我应该手动创建这些类吗?如果没有,怎么办?兰特:必须重复上课似乎很奇怪,所以我一定会对它有所误解?那

  • 问题内容: 假设我在Access中具有以下信息的表格: 我的问题是,如何将第二列中的值连接到基于第一列的行值。我想要的查询结果如下: 我想通过查询来实现。有人可以帮我实现吗? 问题答案: 使用数据的示例:

  • 但我计划为需要多个group BY的报表创建更复杂的查询。我在这里读到了关于多组的正确方法。 如何使用JPA2标准API创建查询?

  • 我有实体类用户通过@IdClass注释使用复合键 复合键: 我将Spring数据与hibernate JPA一起使用。因此,我有回购接口: 我想通过具体姓名和姓氏列表从数据库中获取所有活跃用户。例如。我想使用这样的方法 如何通过Spring数据或JPQL查询此需求?

  • 问题内容: 例如,我有两个实体:雇员和地址。在这些实体中,Employee有一个外键AddressID引用了Address上的ID列。在Java域对象中,Hibernate很好地将forgein键整数字段与Address对象字段包装在一起。但是现在,如何查询具有特定AddressID的Employee? 我试图创建一个表别名。这似乎可行,但相当尴尬。 我也曾尝试做这样的事情: 它有时会起作用,但并