6

我必须关注实体对象


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

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

4

7 回答 7

7

我假设您使用的是实现 JPA 2.0 的 Hibernate 版本。这是一个适用于任何兼容实现的 JPA 2.0 解决方案。

uuids使用 JPA 的注解进行@ElementCollection注解。不要@CollectionOfElements像其他一些答案评论中提到的那样使用 Hibernate。后者具有等效的功能,但已被弃用

Foobar.java看起来大概是这样的:

@Entity
public class Foobar implements Serializable {

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

    @ElementCollection
    private List<String> uuids;

    // Getters/Setters, serialVersionUID, ...

}

这是您如何构建一个CriteriaQuery以选择所有包含“abc123” Foobar的s的方法。uuids

public void getFoobars() {
{
    EntityManager em = ... // EM by injection, EntityManagerFactory, whatever

    CriteriaBuilder b = em.getCriteriaBuilder();
    CriteriaQuery<Foobar> cq = b.createQuery(Foobar.class);
    Root<Foobar> foobar = cq.from(Foobar.class);

    TypedQuery<Foobar> q = em.createQuery(
            cq.select(foobar)
              .where(b.isMember("abc123", foobar.<List<String>>get("uuids"))));

    for (Foobar f : q.getResultList()) {
        // Do stuff with f, which will have "abc123" in uuids
    }
}

我在玩这个的时候做了一个独立的概念验证程序。我现在推不出来。如果您希望将 POC 推送到 github,请发表评论。

于 2010-04-29T22:57:35.827 回答
3

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

如果你想使用 Hibernate Criteria,你可以加入你的uuids集合并使用它的属性elements来匹配元素。就像这样:

session.createCriteria(Foobar.class)
    .createAlias("uuids", "uuids")
    .add(Restrictions.eq("uuids.elements", "MyUUID"))
    .list() 
于 2016-07-01T15:05:22.197 回答
2

您可以使用如下示例中的查询,也可以将其转换为 NamedQuery。不幸的是,似乎没有办法用 Criteria 做到这一点。

List<Foobar> result = session
     .createQuery("from Foobar f join f.uuids u where u =: mytest")
     .setString("mytest", "acb123")
     .list();
于 2010-04-29T15:02:03.523 回答
2

我从一年前发现了这篇文章,并且我已经制作了这个方法,如果它可以帮助任何人解决我几个小时前遇到的同样问题。

    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<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();
    }

它适用于“或”语句,但可以很容易地被“和”语句替换。

于 2011-06-22T18:38:31.810 回答
1

hibernate 不支持您所要求的内容。见http://opensource.atlassian.com/projects/hibernate/browse/HHH-869

这是 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)) ;
于 2010-04-29T16:29:57.390 回答
0

使用 jira http://opensource.atlassian.com/projects/hibernate/browse/HHH-869的 sqlRestriction 的解决方案 对我来说似乎是最好的方法,因为我大量使用标准 api。我不得不编辑 Thierry 的代码,所以它适用于我的情况

模型:

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

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

标准调用:

tCriteria.add(Restrictions.sqlRestriction(
        "{alias}.id in (select e.id from platformData e, platformdata_platformabilities v"
          + " where e.id = v.platformdata_id and v.element = ? )", aPlatformAbility.toString(),
        Hibernate.STRING));
于 2012-11-13T11:17:25.967 回答
-2

对于初学者,我不认为 Hibernate 可以映射一个List<String>. 但是,它可以映射其他实体的列表。

因此,如果您的代码是这样的:

@Entity
public class Foobar {

    private List<EntityObject> uuids;
    ...
}

并且EntityObject有一个String名为 的 -property str,标准可能如下所示:

List<Foobar> returns = (List<Foobar>) session
                .createCriteria.(Foobar.class, "foobars")
                .createAlias("foobars.uuids", "uuids")
                  .add(Restrictions.like("uuids.str", "%abc123%"))
                .list();
于 2010-04-29T07:43:13.367 回答