使用 Hibernate Criteria 过滤 Map 中的键和值

Posted

技术标签:

【中文标题】使用 Hibernate Criteria 过滤 Map 中的键和值【英文标题】:Use Hibernate Criteria for filtering keys and values in Map 【发布时间】:2016-12-26 21:46:27 【问题描述】:

我有以下持久类:

public class Code 

  @ElementCollection(targetClass = CodeValue.class)
  @MapKeyClass(CodeProperty.class)
  @JoinTable(name="code_properties")
  @CreateIfNull( value = false )
  private Map<CodeProperty,CodeValue> propertiesMap =
      new HashMap<CodeProperty, CodeValue>();

  ...


public class CodeProperty 
    private String name;
    ...


public class CodeValue 
    private String value;
    ...

我正在尝试获取由 propertiesMap 中的一些属性过滤的代码列表(例如,名为“color”的属性的值为“green”的代码。

我使用以下基本标准:

Criteria criteria = currentSession()
    .createCriteria(Code.class, "code")
    .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

当我尝试执行收集过滤器时(建议 here):

criteria.createAlias("code.properties", "p");
criteria.add(Restrictions.eq("p.foo", "test1"));
criteria.setFetchMode("code.properties", FetchMode.JOIN);
criteria.list();

我收到以下错误:

org.hibernate.QueryException: could not resolve property: foo of: com.example.CodeValue

这意味着,我真的不明白为什么,hibernate 认为 code.propertiesCodeValue 而不是 ma​​p !!!

我也尝试在不创建别名的情况下访问该字段,这样 hibernate 似乎可以访问正确的 Code 类。我使用了 properties.indeces(建议 here):

criteria.add(Restrictions.eq("properties.indeces", "foo"));
criteria.list();

但是这样我得到以下错误:

could not resolve property: properties.indeces of: com.example.Code

有人可以帮助我了解问题所在吗?找到绿色代码的正确条件查询是什么?

您可以结帐the Github project that demonstrates this problem。

谢谢

【问题讨论】:

我注意到您将 JPA 2.1 功能与 @MapKeyClass 一起使用。您是否一定要使用已弃用的 Hibernate Criteria API 而不是 JPA Criteria API? @Naros 代表 micdcar 回答 - 是的,不幸的是,这意味着将整个 sessionfactory 配置切换到 entitymanager,可以探索但不能在这么短的时间内进行。所以我们必须创建 Criteria,它返回休眠条件。 【参考方案1】:

请确认您是否使用过索引或索引。正确用法如下:

criteria.createAlias("code.properties", "p");
criteria.add(Restrictions.eq("p.indices", "foo"));
criteria.list();

或者,您可以使用

eq("p." + CollectionPropertyNames.COLLECTION_INDICES)  

在限制中。

如果它仍然不适合你,请告诉我。

【讨论】:

【参考方案2】:

这可能不是您所期望的,但在更高版本的 hibernate 中,别名没有得到解决我在使用别名引用时在 Projections 中遇到问题 https://***.com/questions/36607042/hibernate-criteria-query-using-projections-aggregate-function-alias-throws-sette

【讨论】:

【参考方案3】:

您的方法存在各种问题: 在您的项目 github 中查看 MapTest 文件夹,我可以建议您始终将变量名称为列名,并在 Criteria.xml 中使用相同的名称。 Criteria 是映射,其第一个参数是属性名称,第二个参数是属性的值。 对于多对多关系,您可以尝试使用:

  @JoinTable(
      name="docente_classe",
      joinColumns=
          @JoinColumn(name="id_dipendente", referencedColumnName="id_dipendente"),
      inverseJoinColumns=
          @JoinColumn(name="id_classe", referencedColumnName="id_classe")
  )

这是JPA注解,不知道你的项目能不能编译。

https://github.com/tredue1/School_Manager/blob/master/code/SM/src/main/java/agc2/it/sm/gestioneDocente/DocenteJpa.java

关于多对多关系的查询请看这篇文章:

jpa criteria for many to many relationship 。

【讨论】:

对不起,我没有关注。您的示例没有任何地图。查询通过 Sets 实现的多对多是另一回事。您能否使用 GitHub 示例(或项目分支)澄清您的答案? 您是否尝试检查链接:***.com/questions/8135612/… ????这是一个很好的例子。【参考方案4】:

我不相信您可以使用传统的 Hibernate Criteria API 做到这一点,并且使用 JPA 标准 API 的 Hibernate 实现存在一个小的限制。解决此问题的一种方法是:

通过直接使用谓词要求查询该实体来获取List&lt;CodeProperty&gt;

List<CodeProperty> propertyKeys = entityManager
  .createQuery( "FROM CodeProperty p WHERE p.name = :name" )
  .setParameter( "name", "foo" )
  .getResultList();

使用 JPA 标准查询您的 Code 实体。

// setup the query
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Code> query = cb.createQuery( Code.class );
Root<Code> root = query.from( Code.class );
MapJoin<Code, CodeProperty, CodeValue> mapRoot = root.joinMap( "propertiesMap" );
query.select( root ).where( mapRoot.key().in( propertyKeys ) );

// get results
List<Code> results = entityManager.createQuery( query ).getResultList();

我尝试将这些组合使用:

query
  .select( root )
  .where ( cb.eq( mapRoot.key().get( "name" ), "foo" ) )

问题是这会导致NotYetImplemented 异常:(。

【讨论】:

问题是,OP 的问题是关于非实体查询。此外,用 JPA 查询替换 Hibernate Classic Criteria 查询往往会强制更改整个持久性实现(从 SessionFactory 到 EntityManager),这比它的价值要麻烦得多。 @Gwaptiva 理解,但我相信这是用户在从 Hibernate 5 升级到 6 时需要考虑的不可避免的变化。 公平点。我想我可能一直在预测我自己对我的应用程序中的这种变化的恐惧:(

以上是关于使用 Hibernate Criteria 过滤 Map 中的键和值的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate Criteria用法大全

Hibernate Criteria API 中的 SQL 'LIKE' 运算符

使用 Hibernate 的 Criteria 和 Projections 选择多个不同的列

Hibernate 中Criteria Query查询详解

是否可以使用 Criteria 或 DetachedCriteria Hibernate 进行此查询

hibernate hql查询 与Criteria 查询语句区别和效率