2013-02-01 7 views
0

HQL을 사용하여 간단한 select 쿼리를 작성하려고합니다. 쿼리에 사용할 엔터티가 있습니다. 그것은 다음과 같이 보입니다 :상위 - 하위 관계가있는 엔티티 (단일 테이블)에 대한 HQL 쿼리

@Entity 
@Table(name = "my_table") 
public class MyTable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    private Long id; 

    @Column(name = "name") 
    private String name; 

    @Column(name = "test_id") 
    private Long testId; 

    @Column(name = "parent_id") 
    private Long parentId; 

    @OneToMany(mappedBy = "parentId", 
       fetch = FetchType.EAGER, 
       cascade = CascadeType.ALL) 
    private Set<MyTable> children = new HashSet<MyTable>(); 

    //getters and setters 
} 

계층 구조가 간단합니다. 부모 (null parent_id 값을 가짐)와 그 하위가 있습니다. 그래서 두 단계 만.

모든 부모와 그 자녀를 선택하는 쿼리를 만들고 싶습니다. 그러나 아이들을위한 조건이 있습니다. 구체적으로는 test_id과 같아야합니다. 예 : test_id = 1으로 만 아이들을 입원시켜야합니다. 표는 Child1이있는 Parent1 (test_id = 2)과 Child2가있는 Parent2 (test_id = 1)로 구성됩니다. 쿼리 결과는 자식이없는 Parent1과 Child2가있는 Parent2 여야합니다.

검색어 : 결과

from MyTable as myTable left fetch join myTable.children as child 
where child.testId = 1 

는 - 내가 "1"와 자녀가 만 부모를 얻고있다을 test_id. 그러나 필요한 모든 자녀가 없더라도 모든 부모님이보아야합니다. 매핑 또는 쿼리가 잘못되었습니다. 실제로 어떻게되어야합니까?

미리 감사드립니다.

답변

3

매핑이 잘못되었습니다. 단방향 OneToMany 연관이 있습니다. 그래서 당신은 분명히이 연관이 매핑되는 방법을 Hibernate에게 말해야 만한다. 그리고 당신이 말할 것은 :

@OneToMany(mappedBy = "parentId", ...) 

이는 ". 난 단지 역 쪽이야 본 협회가 매핑하는 방법을 찾으려면이 양방향 연관의 다른 측면에서 보면 이동".

하지만 다른면은 없습니다. 귀하의 협회는 단방향입니다.

매핑은해야 다음 parentId 필드가 제거 된

@Entity 
@Table(name = "my_table") 
public class MyTable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    private Long id; 

    @Column(name = "name") 
    private String name; 

    @Column(name = "test_id") 
    private Long testId; 

    @OneToMany(fetch = FetchType.EAGER, 
       cascade = CascadeType.ALL) 
    @JoinColumn(name = "parentId") 
    private Set<MyTable> children = new HashSet<MyTable>(); 

    //getters and setters 
} 

하는 것으로, 이미 아이들의 관계를 매핑하는 데 사용하기 때문이다.

또 다른 문제점은 귀하의 기대입니다. 쿼리가 열을 반환하거나 엔터티를 반환합니다. 부모 엔터티를 반환하고이 엔터티에 자식을 요청하면 모든 자식이 반환됩니다. AN 엔티티는 데이터베이스에있는 항목을 나타냅니다. 특정 쿼리의 결과를 나타내지는 않습니다.

당신이 할 수있는 일은, 아이들 중 일부를 갖고 싶을 때, 아이들을 찾아 부모를 얻는 것입니다. 그렇게하려면, 당신은 협회 양방향해야 할 것 :

@Entity 
@Table(name = "my_table") 
public class MyTable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id") 
    private Long id; 

    @Column(name = "name") 
    private String name; 

    @Column(name = "test_id") 
    private Long testId; 

    @ManyToOne 
    @JoinColumn(name="parentId") 
    private MyTable parent; 

    @OneToMany(mappedBy="parent", 
       fetch = FetchType.EAGER, 
       cascade = CascadeType.ALL) 
    @JoinColumn(name = "parentId") 
    private Set<MyTable> children = new HashSet<MyTable>(); 

    //getters and setters 
} 

을 그리고 쿼리는 다음과 같습니다이 부모와 함께 시험 ID = 1 모든 아이들을 반환

select child from MyTable child 
left join fetch child.parent 
where child.testId = 1 

. 다른 모든 부모를 얻으려면 두 번째 쿼리가 필요합니다.같은 것

select parent from MyTable parent 
where parent.id not in (
    select parent2.id from MyTable child 
    left join child.parent parent2 
    where child.testId = 1) 
+0

예, 동일한 매핑을 시도한 다음 bidirectical 매핑을 제거하려고했습니다. 잘 작동합니다 (잘 모름). 어쨌든 설명 해줘서 고마워요. 실제로 정확한 쿼리가 검색되었습니다. 나는 어쩌면 불필요한 아이들없이 부모를 얻는 방법이 있을지도 모른다고 생각했다. 하지만 ... 당신의 재계에 감사드립니다. –