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元素
。