我正在使用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。