2017-03-13 5 views
0

나는 부모 인 Cat 엔티티, 일대 다 자식 콜렉션 인 CatDts를 얻었다. CatDt.name = 'a'인 모든 Cat을 가져오고 싶습니다. 생성 된 SQL 쿼리는 정확하지만 CatDts 컬렉션에 액세스 할 때 'a'라는 이름이 아닌 모든 자식 레코드가 반환됩니다. 어떤 도움을 주셔서 감사합니다, 감사합니다!Hibernate는 제한된 자식뿐만 아니라 부모의 모든 자식 레코드를 가져온다.

테이블

Cat   CatDt 
id   id  name cat_id 
----  ---  ---  --- 
1   100  a  1 
2   101  a  2 
      102  xyz  2 

그래서 난 그냥 1-100, 2-101 필요하지만, 그것은 또한 나에게

private List<CatDt> catDts = new ArrayList<CatDt>(); 

@OneToMany(fetch = FetchType.LAZY, mappedBy = "cat", cascade=CascadeType.ALL) 
public List<CatDt> getCatDts() { 
    if(this.catDts==null){ 
     this.catDts = new ArrayList<CatDt>(); 
    } 
    return this.catDts; 
} 

CatDt을 2-102

고양이 개체를 제공합니다 엔티티

private Cat cat; 

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) 
    @JoinColumn(name = "CAT_ID", nullable = false) 
public Cat getCat() { 
    return this.cat; 
} 

서비스

public List<Cat>findAllByOption(CatOption options){ 
    QCat cat = QCat.cat; 
    QCatDt catDt = QCatDt.catDt; 
    List<Cat> cats = jpaQueryFactory.selectFrom(cat)     
       .innerJoin(catDt).on(cat.id.eq(catDt.cat.id).and(catDt.name.eq("a"))) 
       .where(cat.status.eq(new BigDecimal(0))).fetch(); 
    return cats; 
} 

테스트 나 테스트 라인 아래에서 로그를 확인하고 찾을 수

@Test 
public void testCatWithOptionsJpaQuery(){ 
    CatOption options = new CatOption(); 
    options.setStatus(new BigDecimal(0)); 
    options.setName("a"); 
    List<Cat> catList = catService.findAllByOption(options); //-->returns 2 rows 
    for(Cat cat:catList){ 
     logger.info("--" + cat.toString()); //-->gets the child collection catDts and pulls out all rows, not just constrained ones 
    } 
    Assert.notNull(catList, "categories returned cannot be null!"); 
} 

, SQL 쿼리 & 가입은 2 개 행을 반환, 좋은 고양이. 나는 그 2 고양이 개체를 반복 할 때

catService.findAllByOption(options) 

는하지만, 최대 절전 모드 (3 총) 모든 correspoding CatDt 하위 집합을 가져옵니다. 그래서 어떻게 name = 'a'인 자식 레코드를 얻을 수 있습니까?

업데이트 1

실행이 테스트에서 루프 내에서 선 아래에 도달

, 그것은 그 3 개 기록 (2)의 난이 ORM이 얼마나 생각 대신에 반환되는 방법, 개별 선택 문을 던졌습니다 일을해야하지만 제한된 어린이를 얻는 방법은 무엇입니까?

logger.info("--" + cat.toString()) 
+0

나는 이것이 최대 절전 모드 동작이라고 생각한다. 그래서 우리는 서비스/저장소 레벨에서 필터링을하고, FilterDef와 Filter를 사용하여 엔티티 Hibernate 레벨에서 다시 필터링해야합니다. 그렇게하지 않는가? ** 두 번 **? 서비스/저장소 수준에서 페치 할 때 자녀를 필터링 된 컬렉션으로 설정하지 못할 수 있습니까? 우리가 150 개 이상의 엔티티에 대해 그렇게한다면, Hibernate/Spring Data는 우리에게 이러한 저수준 요소를 추상적으로 사용하기로되어 있기 때문에 목적을 상실하게됩니까? –

+0

그리고 여러 부모 집합 (여러 자식 집합 함께 child1, 자식 2 모임 조건을 말한다) 부모 및 여러 자식 일치하는 여러 조건을 일치하는 경우에만 가져 가야 할 경우 querydsl/predicates 및 repo 데이터를 가져올합니까? 일치하는 모든 부모를 얻습니다. 그러나 parent1.getChild1()을 호출하면 제한된 집합이 아닌 전체 집합이 다시 반환됩니다. 그래서 우리는 각 자식에 대해 Hibernate Filter를 설정하고, 반환 된 부모를 반복하고 모든 자식 세트를 가져와야합니까? 이것은 틀리게 들린다. 제발 조언. –

+0

OK 그래서 우리는 리턴 된 모든 부모를 루핑 한 다음 관련 아이를 얻고 그들을 설정함으로써 수동으로 끝낼 수 있습니다. 물론 이것이 올바른 방법이 아닙니까? 내가 한 일은 부모 서비스, loop & call child service.findAll (options)이었고, 자식 id의 부모 id를 확인하고, set을 추가하고, parent를 추가했다. –

답변

0

그래서 나는 내가 필요로하는 모든 결과 필드를 포함하는 pojo를 생성함으로써 문제를 해결했습니다.

내 서비스/레포는 querydsl을 사용하여 & 필터에 가입했습니다. 반환 된 서비스 목록입니다.

나는 Hibernate가 하나의 테이블에 대해 훌륭하다고 생각하지만, 복잡한 조인과 결과를 위해서 우리는 커스텀 객체와 Querydsl을 사용할 수있다.

다른 방법으로 부모 노드를 반복하고 Hibernate의 @Filter를 사용할 수도 있습니다.