【问题标题】:Hibernate: search for entities that contains a value in a set of enumsHibernate:在一组枚举中搜索包含值的实体
【发布时间】:2014-08-26 19:58:10
【问题描述】:

我有一个类似于以下示例的实体:

@Entity
@Table(name = "AIRPLANE")
public class Airplane {

    @ElementCollection(targetClass = Color.class, fetch = FetchType.LAZY)
    @CollectionTable(name = "AIRPLANE_COLORS", joinColumns = @JoinColumn(name = "AIRPLANE_ID"))
    @Column(name = "AIRPLANE_COLOR")
    @ForeignKey(name = "FK_AIRPLANE_COLOR_ID")
    @Enumerated(EnumType.STRING)
    private Set<Color> colors;    
    ...
}
...
public enum Color {
    WHITE, RED, BLUE
}

其中颜色是一组枚举,我想搜索包含此集中颜色 RED 的所有实体 Airplanes。

我可以使用 Criterias 还是应该使用 HQL 查询?

谢谢!

【问题讨论】:

    标签: java hibernate enums set criteria


    【解决方案1】:

    有一种方法可以在 Hibernate 中使用 Criteria 执行此类查询。你只需要加入colors 并请求它的elements 属性(即colors.elements)。

    elements 是在 Hibernate 的 CollectionPropertyNames 类中定义的关键字,您可以使用它访问您的枚举值。

    session.createCriteria(Airplane.class)
        .createAlias("colors", "colors")
        .add(Restrictions.eq("colors.elements", Color.BLUE))
        .list() 
    

    【讨论】:

      【解决方案2】:

      标准 API 对于基于一组动态的...标准创建查询很有用。对于静态查询,HQL 总是更具可读性:

      select a from Airplane a where :color member of a.colors
      

      select a from Airplane a join a.colors color where color = :color
      

      应该做的伎俩

      【讨论】:

      • 这和我的查询是一样的,只是它没有选择子句。我建议你总是有一个 select 子句:它更清晰,如果你希望你的查询符合 JPA 并因此是可移植的,它是强制性的。
      • 颜色属性是一个集合。不是最初的问题,而是:如何为具有两种颜色的飞机编写查询? (也许威斯康星州球迷的红白相间?:)
      【解决方案3】:

      按照 JB Nizet 的建议,您可以使用HQL 来获取结果:

              Query query = session.createQuery("from Airplane as airplane inner join "
                      + "airplane.colors colors where colors =:color");
              query.setParameter("color", Color.BLUE);
      
              List<Airplane> list = query.list();
              for (Airplane airplane : list) {
                  System.out.println("->" + airplane.getColors());
              }
      

      【讨论】:

      • 应该是query.setParameter("color", Color.BLUE)
      • 感谢 JB,我尝试使用 setString,这也有效,但 setParameter 是正确的做法。现在更新我的答案。
      • 尝试使用@Enumerated(EnumType.ORDINAL),我怀疑它可以通过传递字符串来工作。如果你通过枚举,它会。
      • 如果我添加@Enumerated(EnumType.ORDINAL),那么setParameter 工作正常,但setString 抛出错误ERROR: ORA-01722: invalid number
      • 这段代码运行良好,谢谢。通常,我使用 EnumType.STRING 进行枚举映射,因为如果有人修改枚举中值的顺序,不会破坏数据库中的任何内容
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-02
      相关资源
      最近更新 更多