Criteria API - Using UPPER in a ElementCollection

喜夏-厌秋 提交于 2020-07-21 07:19:12

问题


I have a class

@Entity
public class Person{
...
@ElementCollection
private Set<String> tags;
...
}

I want to use the JPA 2.0 Criteria API to search over these tags - but in a case insensitive way. Thus I want to both set the search parameter to UPPER and the column to UPPER (Pseudo-SQL: select p.* from Person p join Tags t on p.id=t.pId where upper(t.name)=upper('searchParameter'); )

Here is my code without the UPPER on the tags:

  CriteriaBuilder builder = this.em.getCriteriaBuilder();
  CriteriaQuery<Person> query = builder.createQuery(Person.class);
  Root<Person> root = query.from(Person.class);

  return this.em.createQuery(query.select(root).where(
     builder.isMember(builder.upper(builder.literal(searchTag)),
        root.get(Person_.tags)))).getResultList();

where searchTag is the input parameter.

How can I assign the UPPER to the Person_.tags "Column"?

In other words I want to write this Query with Criteria API:

SELECT p FROM Person p JOIN p.tags t WHERE UPPER(t) = UPPER('searchString')

Thank you


回答1:


Ok, I finally have the solution:

  cQuery.where(
     builder.equal(
        builder.upper(cQuery.from(Relation.class).join(Relation_.aliase)
           .as(String.class)),
        builder.upper(builder.literal(alias))
        )
     );

One has to use the ".as(..)" method.




回答2:


suburbCriteria = criteriaBuilder.equal( 
                    criteriaBuilder.upper(root.get(Property_.suburb)), 
                    criteriaBuilder.upper(criteriaBuilder.literal(searchBean.getSuburb())));



回答3:


You need to call upper and literal property name on joined Tags from Person.

CriteriaBuilder builder = this.em.getCriteriaBuilder();
CriteriaQuery<Person> query = builder.createQuery(Person.class);
Root<Person> root = query.from(Person.class);
Join<Person, Tag> tags = root.join(Person_.tags);

query.where(builder.isMember(
        builder.upper(builder.literal(searchTag)), 
        builder.upper(builder.literal(tags.get(Tag_.name)))
));

return this.em.createQuery(query).getResultList();

I omitted query.select(root), not sure if it is required. Tou can also omit builder.literal() on Tag_.name since is String.

If I am wrong somewhere, please edit my answer for further users.

Hope this helps.



来源:https://stackoverflow.com/questions/10192094/criteria-api-using-upper-in-a-elementcollection

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!