2012-03-14 4 views
1

나는 SQL 쿼리 경우왜 JPA 조인이 너무 많은 결과를 반환합니까?

select * from Profesor 
inner join Estudiantes on Profesor.id = Estudiante.id 
where Profesor.nombre = 'juan' 
    and Estudiante.nombre = 'jose' 

이 쿼리는 profesor 학생을 반환합니다. 한 명의 교수와 한 명의 학생. Jues Professor Juan, 호세와 학생.

는 다음 JPA에서 I 쿼리 경우 :

select p from Profesor p 
inner join p.estudiantes e 
where p.nombre = juan 
    and e.nombre = jose. 

JPA는 모든 학생들과 함께 목록을 가지고 모든 학생들이 아니라 하나의 내가 원하는 profesor.estudiantes로 돌아 profesor 후안 것입니다.

내 유형은 다음과 같습니다 스페인어

class Profesor{ 
    private List<Estudiante> estudiantes; 
} 

class Estudiante{ 
    String matricula; 
} 

미안 코드입니다. 나는 이것을 알아 낸다.

내가 내 질문에 명확한 지 모르겠다 고 말해주십시오.

+0

검색어가 "시도한 그대로"(간단한 구문 오류로 인해 사람들을 벗어날 것임)하십시오. –

답변

2

두 가지를 이해해야합니다.

첫 번째 : Select p from Profesor이라고 말하면 JPA는 Profesor 테이블의 열만 선택하고 아직로드되지 않은 학생 컬렉션이 포함 된 Profesor 인스턴스를 반환합니다. 처음 컬렉션에 실제로 액세스 할 때 느리게로드됩니다. 그리고 콜렉션을로드 할 때, 교수님을로드하는 데 사용 된 쿼리를 잊어 버렸습니다. 그것이로드하는 것은 교수의 학생들의 수집입니다. 그리고 교수는 많은 학생들이 있기 때문에, 그것들을 모두 먹는다. 초기 쿼리는

과 비슷합니다.
select p.* from Profesor inner join ... 

SQL로 실행하면 교수와 학생이로드되지 않습니다. 그것은 단지 교수를 불러들입니다.

두 번째 : 엔티티가 데이터베이스의 데이터를 나타내야합니다. 그것은 질의의 결과를 나타 내기로되어 있지 않습니다. 그래서, 교수 실체에있는 학생들의 수집은 항상 교수의 모든 학생들의 수집입니다.

  1. select p, s from Profesor inner join p.students s... :

    는 몇 가지 선택이있다, 당신이 원하는 일을하려면이 발견 profesor를 포함한 배열하고, 발견 된 학생을 반환합니다. select s from Profesor p inner join p.students s ... :이 학생을로드하고, 그 교수가이 분야에서 JPA 스펙 위반하는 최대 절전 모드 사용
  2. 경우 참조 : select p from Profesor inner join fetch p.students...를 : 페치 차종은 교수와 학생들을로드 최대 절전 모드
  3. 협회가 양방향 경우
  4. 단일 쿼리에서. 그러나 학생에게 where 절을 추가 했으므로 교수의 일치하는 학생 만로드합니다.

세 번째 솔루션은 매우 위험한 솔루션이므로 사용을 권하지 않습니다. 먼저 유효한 JPQL이 아니기 때문입니다. 더 중요한 것은, 그러한 쿼리로로드 된 Professor 엔티티를 가져 오는 코드가 professor.getStudents()가 그 중 하나가 아닌 교수의 모든 학생을 반환 할 것으로 예상하기 때문입니다. 따라서 잘못된 결과를 표시하거나 수집을 수정하여 데이터베이스에서 인코 오네를 일으킬 수 있습니다.

+0

Profesor inner p.students s ...에서 0121, p, s를 선택하십시오. 테스트가 어렵습니다. –

관련 문제