Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么JPA join返回太多结果?_Java_Jpa_Join_Jpql - Fatal编程技术网

Java 为什么JPA join返回太多结果?

Java 为什么JPA join返回太多结果?,java,jpa,join,jpql,Java,Jpa,Join,Jpql,如果我在SQL中查询: select * from Profesor inner join Estudiantes on Profesor.id = Estudiante.id where Profesor.nombre = 'juan' and Estudiante.nombre = 'jose' 此查询返回教授和学生。一名教授和一名学生。只有胡安教授和何塞是学生 如果我在JPA中查询: select p from Profesor p inner join p.estudiantes

如果我在SQL中查询:

select * from Profesor
inner join Estudiantes on Profesor.id = Estudiante.id
where Profesor.nombre = 'juan'
  and Estudiante.nombre = 'jose'
此查询返回教授和学生。一名教授和一名学生。只有胡安教授和何塞是学生

如果我在JPA中查询:

select p from Profesor p
inner join p.estudiantes e
where p.nombre = juan
  and e.nombre = jose.
JPA将返回Juan教授和所有学生,而不仅仅是我想要的学生,
profesor。eStudients
将有所有学生的名单

我的类型是:

class Profesor{
    private List<Estudiante> estudiantes;
}

class Estudiante{
    String matricula;
}
class教授{
私人名单学生;
}
班级学生{
弦矩阵;
}
对不起,我用西班牙语编码。我只是想弄明白


我不知道我的问题是否清楚,请告诉我。

你需要了解两件事

第一:当您说
从Profesor选择p
时,JPA只从Profesor表中选择列,并返回一个Profesor实例,其中包含尚未加载的学生集合。当您第一次实际访问集合时,它将被延迟加载。当它加载集合时,它忘记了您用于加载教授的查询。它装载的是教授的学生集合。因为一个教授有很多学生,它;把他们都干掉。初始查询类似于

select p.* from Profesor inner join ...
在SQL中执行它,您将看到它不会加载教授及其学生。这只会让教授感到厌烦

第二:实体应该表示数据库中的数据。它不应该表示查询的结果。因此,教授实体中的学生集合始终是教授的所有学生的集合

要想做你想做的事,你有几个选择:


  • 从Profesor internal join p.students s s.选择p,s.。
    :这将返回一个数组,其中包含找到的Profesor和找到的student
  • 如果关联是双向的:
    从Profesor p internal join p.students s s中选择s…
    :这将加载学生,并引用其教授
  • 如果使用Hibernate,这违反了此区域的JPA规范:
    select p from Profesor internal join fetch p.students…
    :fetch使Hibernate在单个查询中加载教授及其学生。但是,由于您在学生上添加了where子句,因此它只加载教授的匹配学生

  • 请注意,第三种解决方案非常危险,我不建议使用它。首先是因为它不是有效的JPQL。更重要的是,因为通过这样的查询加载Professor实体的代码期望Professor.getStudents()返回Professor的所有学生,而不仅仅是其中一个。因此,它可能会显示错误的结果,或修改集合并导致数据库不一致。

    请确保查询“与尝试的完全一样”(一个简单的语法错误会让人发疯)从Profector或Internal join p中选择p,s。学生s。。。我来测试一下。