Java Hibernate Criteria API-添加条件:字符串应在集合中

Java Hibernate Criteria API-添加条件:字符串应在集合中,java,hibernate,jpa,criteria,criteria-api,Java,Hibernate,Jpa,Criteria,Criteria Api,我必须跟踪实体对象 @Entity public class Foobar { ... private List<String> uuids; ... } @实体 公共级Foobar{ ... 私有列表uuid; ... } 现在我想做一个条件查询,它将获取uuids列表包含字符串“abc123”的所有Foobar POJO,我只是不确定如何制定适当的条件。对于初学者,我认为Hibernate无法映射列表。但是,它可以映射其他实体的列表 如果你的代码是

我必须跟踪实体对象


@Entity
public class Foobar {
    ...
    private List<String> uuids;
    ...
}

@实体
公共级Foobar{
...
私有列表uuid;
...
}

现在我想做一个条件查询,它将获取uuids列表包含字符串“abc123”的所有Foobar POJO,我只是不确定如何制定适当的条件。

对于初学者,我认为Hibernate无法映射
列表。但是,它可以映射其他实体的列表

如果你的代码是这样的:

@Entity
public class Foobar {

    private List<EntityObject> uuids;
    ...
}
List<Foobar> returns = (List<Foobar>) session
                .createCriteria.(Foobar.class, "foobars")
                .createAlias("foobars.uuids", "uuids")
                  .add(Restrictions.like("uuids.str", "%abc123%"))
                .list();
@Entity
public class Foobar implements Serializable {

    // You might have some other id
    @Id
    private Long id;

    @ElementCollection
    private List<String> uuids;

    // Getters/Setters, serialVersionUID, ...

}

您可以使用下面示例中的查询,也可以将其转换为NamedQuery。不幸的是,似乎没有一种方法可以通过标准来做到这一点

List<Foobar> result = session
     .createQuery("from Foobar f join f.uuids u where u =: mytest")
     .setString("mytest", "acb123")
     .list();
列表结果=会话
.createQuery(“从Foobar f join f.uuids u,其中u=:mytest”)
.setString(“mytest”、“acb123”)
.list();

hibernate不支持您提出的问题。看

以下是jira票证中提供的解决方法:

entityCriteria.add(Restrictions.sqlRestriction(
  "fooAlias.id in (select e.id from foobar_table e, values_table v" + 
  " where e.id = v.entity_id and v.field = ?)", "abc123"), Hibernate.String)) ;

我假设您使用的是实现JPA2.0的Hibernate版本。这里有一个JPA2.0解决方案,它可以与任何兼容的实现一起工作

请用JPA的
@ElementCollection
注释
uuids
。不要使用Hibernate的
@collectionfements
,如其他一些答案注释中所述。后者具有相同的功能,但功能不同

Foobar.java
大致如下:

@Entity
public class Foobar {

    private List<EntityObject> uuids;
    ...
}
List<Foobar> returns = (List<Foobar>) session
                .createCriteria.(Foobar.class, "foobars")
                .createAlias("foobars.uuids", "uuids")
                  .add(Restrictions.like("uuids.str", "%abc123%"))
                .list();
@Entity
public class Foobar implements Serializable {

    // You might have some other id
    @Id
    private Long id;

    @ElementCollection
    private List<String> uuids;

    // Getters/Setters, serialVersionUID, ...

}

在玩这个游戏的时候,我制作了一个独立的概念验证程序。我现在不能把它推出去。如果您希望将POC推送到github,请发表评论。

我在一年前找到了这篇文章,并且我采用了这种方法,如果它可以帮助任何人解决我几个小时前遇到的问题

    Public List<EntityObject> getHasString(String string) {
        return getSession().createCriteria(EntityObject.class)
                               .add(Restriction.like("property-name", string, MatchMode.ANYWHERE).ignoreCase();
                           .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                           .list();
Public List gethastring(字符串){
返回getSession().createCriteria(EntityObject.class)
.add(Restriction.like(“property name”、string、MatchMode.ANYWHERE).ignoreCase();
.setResultTransformer(标准.DISTINCT\u ROOT\u实体)
.list();
用一组字符串也做了同样的事情

    public List<EntityObject> getByStringList(String[] tab) {
        Criterion c = Restrictions.like("property-name", tab[tab.length-1], MatchMode.ANYWHERE).ignoreCase();
        if(tab.length > 1) {
            for(int i=tab.length-2; i >= 0 ; i--) {
                c = Restrictions.or(Restrictions.like("property-name",tab[i], MatchMode.ANYWHERE).ignoreCase(), c);
            }
        }
        return getSession().createCriteria(EntityObject.class)
                               .add(c)
                           .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                           .list();
    }
公共列表GetByString(字符串[]选项卡){ 条件c=限制。例如(“属性名称”,tab[tab.length-1],MatchMode.ANYWHERE)。ignoreCase(); 如果(制表符长度>1){ 对于(int i=tab.length-2;i>=0;i--){ c=限制。或(限制。如(“属性名称”,选项卡[i],匹配模式.ANYWHERE)。ignoreCase(),c); } } 返回getSession().createCriteria(EntityObject.class) .添加(c) .setResultTransformer(标准.DISTINCT\u ROOT\u实体) .list(); }

它与“或”语句一起工作,但可以很容易地用“和”语句替换。

使用jira的sqlRestriction的解决方案 对我来说,这似乎是最好的方法,因为我大量使用CriteriaAPI。我必须编辑Thierry的代码,以便在我的情况下工作

型号:

@Entity
public class PlatformData
{
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long iID;

  private List<String> iPlatformAbilities = new ArrayList<String>();
}

我知道这是一个老问题,但我刚刚遇到了这个问题并找到了解决办法

如果要使用Hibernate条件,可以加入
UUID
集合,并使用其属性
elements
匹配元素。就像这样:

session.createCriteria(Foobar.class)
    .createAlias("uuids", "uuids")
    .add(Restrictions.eq("uuids.elements", "MyUUID"))
    .list() 

使用字符串列表没有问题,只需使用@CollectionFelements对其进行注释。您的解决方案需要我创建一个额外的实体类,这是我希望通过这个非常具体的问题避免的。尝试使用hibernate 3.6.7-Final,但不起作用(这似乎是hibernate中的一个错误)。您也可以使用而不是“元素”常量
CollectionPropertyNames.COLLECTION\u元素