2012-07-03 2 views
5

그래서 Users 테이블, Projects 테이블 및 User_Roles 테이블이 있습니다. 나는 2 명의 프로젝트에 연결된 하나의 사용자를 가지고 있지만, 나는 그에게 2 개의 프로젝트를 반환하지만, 그를 위해 2 개의 역할을한다면 4 개의 역할 (2x2 프로젝트)을 반환한다. 어떻게이다른 테이블에 중복 된 값이 있기 때문에 Hibernate가 중복을 반환합니다.

이 사용자 클래스에서 사용자에 대한

@Override 
public List<Project> retrieve(User user) { 
    Criteria criteria = super.createCriteria(); 
    criteria.addOrder(Order.desc("date")); 
    criteria.createCriteria("users").add(Restrictions.eq("id", user.getId())); 

    return (List<Project>) criteria.list(); 
} 

매핑 프로젝트 목록을 반환하는 내 코드

@ManyToMany(cascade = CascadeType.ALL) 
@JoinTable(name = "Users_Projects", 
      joinColumns = @JoinColumn(name = "UserID"), inverseJoinColumns = @JoinColumn(name = "ProjectID")) 
public List<Project> getProjects() { 
    return projects; 
} 

@ElementCollection(fetch = FetchType.EAGER) 
@Enumerated(EnumType.STRING) 
@Column(name = "RoleType") 
@JoinTable(name = "User_Roles", joinColumns = @JoinColumn(name = "UserID")) 
public Set<Role> getRoles() { 
    return roles; 
} 

어떤 제안 문제가 여기에 무엇됩니다 방지합니까?

TNX는

답변

13

당신은 페이지 매김과 결합하는 것을 시도하지 않는로서 가능성이 한 작동 기준 쿼리에서 중복 행의 문제에 대한 고전적인 "수정", 추가하는 것입니다

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 

나는 사용자 역할이 열심히로드되기 때문에 이러한 상황이 발생했다고 생각합니다. 게으르도록 변경하면 작업 할 수도 있고 페이지 매김이 필요한 경우 계속해서 작업 할 수도 있습니다.

설정 fetch = FetchType.EAGER은 항상 사용자를 검색 할 때마다 항상 사용자의 모든 역할을로드하려는 사용자에게 최대 절전 모드를 지시합니다. 사용자는 항상 역할 테이블에 대한 조인을 수행하여이를 수행합니다.

아쉽게도 SQL은 동일한 사용자 (각 역할마다 하나씩)가있는 여러 레코드로 이어지고 SQL이 실행 된 후 Java에서 곧바로 변환되어야합니다. 결과 변환자가 수행하는 것입니다.

criteria.setFirstResultcriteria.setMaxResults을 사용하여 간단한 최대 절전 기준으로 가장 자연스러운 방식으로 페이징을 사용하려는 경우 상황이 잘못된 순서로 발생하므로 중복되는 것을 피하기 위해 결과 변환기가 필요한 이러한 쿼리는 ' T 페이지 오른쪽.

모든 hibernate sql generation을 좀 더 잘 이해하려면 this answer에 설명 된대로 생성 된 sql의 로깅을 켜두는 것이 좋습니다.

+1

감사합니다. 매력처럼 작동하지만, 왜 역할로드로 인해이 문제가 발생하는지 설명 할 수 있습니까? 나는 또한 이것이 사실이라고 확신하지만, 왜 사용자 - 프로젝트의 연결 부분이 아닌 무언가를 설정하면이 문제가 발생합니다. 이견있는 사람? –

+0

귀하의 의견에 조금 더 질문에 대한 내 업데이 트를 참조하십시오. –

관련 문제