【问题标题】:JPQL does not work properlyJPQL 无法正常工作
【发布时间】:2017-04-20 02:52:01
【问题描述】:

父类:

@Table(name = "users")
class User {
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
List<Gender> genders = new ArrayList<>();

儿童班:

@Table(name = "gender")
class Gender {
@ManyToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "userId", nullable = false)
User user;
String sex;

我在 MySQL 中的目标:

SELECT * FROM users a LEFT JOIN genders b ON a.id=b.id WHERE b.sex='dasd'

返回 1 行 它运作良好。我只有一条符合这个条件的记录。

但 JPQL 中的代码相同:

SELECT a FROM Users a LEFT JOIN a.genders b WHERE b.sex ='dasd'

返回: 一个用户 - 正确和表 Gender 中的所有性别,但我不想只有当 sex ='dasd' 并且只有一个满足此条件的记录时才想要所有。btw JPQL generateN+1 issue 并且对于每个子查询忽略条件性 ='达斯德'

如何编写满足条件的子查询?我可以强制子查询只返回与 JPQL 查询匹配的性别吗?

【问题讨论】:

  • 能否提供性别实体代码?
  • 我还包括了 Gender.java(child)

标签: mysql spring hibernate spring-data jpql


【解决方案1】:

在 JPQL 中,您从实体而不是表中选择,

SELECT a FROM User a LEFT JOIN a.genders b WHERE b.sex ='dasd'

由于您将 a.genders 列表配置为 EAGER,因此每次选择用户时,它都会获取与该用户关联的所有性别。即使它们与 JPQL 查询不匹配。

如果您将 a.genders 列表设置为 LAZY,它不会获取任何 Gender,因为您仅从 User 中选择

那个查询等价于 SQL

SELECT a.* FROM users a LEFT JOIN genders b ON a.id=b.id WHERE b.sex='dasd'

如果你只想选择一个性别

SELECT b FROM Gender b WHERE b.user = :user AND b.sex = 'dasd'

【讨论】:

  • 每次您选择一个用户时,它都会获取该用户关联的所有性别。即使它们与 JPQL 查询不匹配。是的,这就是问题。我可以强制它只返回与 JPQL 查询匹配的 Gender 吗?
  • 问题是您没有选择性别,而是选择了用户。如果您使用 EAGER,则性别集合将使用完整集合进行初始化。如果您使用 LAZY,genders 集合将使用一个代理初始化,该代理将在需要时获取整个集合(如果您这样做 a.getGenders() )。我已经编辑了关于如何选择一种性别的答案。
  • 不符合标准。问题是您正在查询用户。如果您只想选择一个性别,请使用 select from gender 查询。
  • 我想查询用户和性别。不是单独的。在原始 SQL 中它可以工作。我会尝试用 mybatis 来做。
猜你喜欢
  • 2016-12-01
  • 1970-01-01
  • 2016-09-01
  • 2012-07-11
  • 2018-04-08
  • 2018-10-02
  • 2016-09-04
  • 2010-10-06
  • 2011-11-13
相关资源
最近更新 更多