【问题标题】:How to query OneToOne entity for specific value with CriteriaQuery如何使用 CriteriaQuery 查询 OneToOne 实体的特定值
【发布时间】:2018-12-28 16:52:21
【问题描述】:

我有一个实体 (Person),它是另一个实体 (User) 的 OneToOne。我需要使用 CriteriaQuery 查找与 User.name 匹配的所有 Person 实体。

我可以对 Person 的直接属性做简单的 CriteriaQuery 就好了:

builder.like(builder.lower(root.get(column)), "%" + pattern.toLowerCase() + "%")

在这种更复杂的情况下,我对如何进行 CriteriaQuery 查询有点迷茫。从我在这里和其他地方的搜索来看,我认为我必须使用某种 Join,但我无法理解它。

@Entity()
public class Person extends ModelCore {
    @Basic()
    private String iD = null;
    @OneToOne(cascade = { CascadeType.ALL })
    @JoinColumns({ @JoinColumn(name = "T_User") })
    private User user = null;
}

@Entity()
public class User extends ModelCore {
    @Basic()
    private String iD = null;
    @Basic()
    private String name = null;
}

@Entity()
public class ModelCore{
    @Basic()
    private Long dbID = null;
}

已解决

Nikos 的解决方案效果很好(谢谢!):

String username = ... // the criterion
EntityManager em = ...
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> query = cb.createQuery(Person.class);
Root<Person> root = query.from(Person.class);
Join<Person, User> joinUser = root.join("user"); 
query.where(cb.like(cb.lower(joinUser.get("name")), "%" + username.toLowerCase() + "%"));

编辑 1:添加 ModelCore 作为基类。 编辑 2:添加工作解决方案

【问题讨论】:

  • 您将如何使用 JPQL 查询,甚至是 SQL 查询来做到这一点?

标签: java hibernate jpa hibernate-criteria


【解决方案1】:

随着复杂性的增加,Criteria API 可能会令人困惑。我始终遵循的第一步是写下 JPQL 查询。在这种情况下:

SELECT p
FROM Person p
  JOIN User u
WHERE LOWER(u.name) LIKE :username

将其转换为 Criteria API 是:

// These are initializations
String username = ... // the criterion
EntityManager em = ...
CriteriaBuilder cb = em.getCriteriaBuilder();
// Next line means "the result of the query is Person"
CriteriaQuery<Person> query = cb.createQuery(Person.class);
// This matches the "FROM Person p" part of the JPQL
Root<Person> root = query.from(Person.class);
// This matches the "JOIN User u" part of the JPQL
Join<Person, User> joinUser = root.join("user"); // if you have created the metamodel, adjust accordingly
// This is the "WHERE..." part
query.where(cb.like(cb.lower(joinUser.get("name")), "%" + username.toLowerCase() + "%"));

WHERE 部分令人困惑,因为您必须将中缀 SQL/JPQL 运算符转换为前缀(即 x LIKE y 变为 cb.like(x, y)),但映射很简单。

【讨论】:

  • Nikos:感谢您提供非常清晰的解决方案。不幸的是,它对我不起作用。请参阅我已更新的帖子。我原来的示例类显然过于简化了。
  • Root root = query.from(User.class);应该是 Root root = query.from(Person.class);
  • @MikeCooper: 更正Root&lt;User&gt; root -> Root&lt;Person&gt; 可能是失败的原因,你能用新代码检查一下吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-08
  • 2019-10-07
  • 2016-01-01
  • 2013-06-07
  • 2016-07-11
  • 1970-01-01
  • 2020-12-27
相关资源
最近更新 更多