2016-10-10 3 views
0

Criteria API를 사용하여 플레이어와 계층 구조의 Manager를 결합 할 수있는 방법이 있습니까? 나는 내 DAO에 주어진 ID의 관리자로 모든 플레이어를 찾을 좋아하고이 같은 시도 것 :JPA 2 추상 수집과 결합한 기준

검색어 :

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Player> query = cb.createQuery(Player.class); 
Root<Player> root = query.from(Player.class); 

Join<Player, PlayerTeam> playerTeamJoin = root.join(Player_.playerTeam); 
Join<PlayerTeam, PlayerTeamAssignment> playerTeamAssignmentJoin = playerTeamJoin.join(PlayerTeam_.playerTeamAssignments); 

// Desired statement: 
Predicate predicate = cb.equal(playerTeamAssignmentJoin.get(ManagerAssignment_.manager), manager); 

클래스 계층 구조 :

@Entity 
class Player { 
    @OneToOne(mappedBy = "player") 
    PlayerTeam playerTeam; 
} 

@Entity 
class PlayerTeam { 
    @JoinColumn(name = "PLAYER_ID", referencedColumnName = "ID") 
    Player player; 
    @OneToMany(mappedBy = "playerTeam") 
    Collection<PlayerTeamAssignment> playerTeamAssignments; 
} 

@Entity 
@DiscriminatorColumn(name = "ASSIGNMENT_TYPE", discriminatorType = DiscriminatorType.STRING) 
public abstract class PlayerTeamAssignment { // It has three implementations 
    @ManyToOne 
    @JoinColumn(name = "PLAYER_TEAM_ID", referencedColumnName = "ID") 
    PlayerTeam playerTeam; 
} 

@Entity 
@DiscriminatorValue("INDIVIDUAL") 
public class ManagerAssignment extends PlayerTeamAssignment { 
    @ManyToOne 
    @JoinColumn(name = "MANAGER_ID", referencedColumnName = "ID") 
    Manager manager; // id inside 
} 
+0

나는 데이터 모델은 일부 재 작업을해야 할 수도 있습니다 생각합니다. – JimmyB

+0

답변 해 주셔서 감사합니다. 것은 수정할 수 없다는 것입니다. 클래스 이름은 질문 목적으로 단순화되었습니다. 실제로는 좀 더 복잡한 구조를 나타냅니다. – Macieyo

+0

'PlayerTeamAssignment'에는'manager' 필드가 없습니다. 'ManagerAssignment'에서 'SELECT ... FROM ManagerAssignment JOIN ...'의 쿼리를 시작하지 않으시겠습니까? – JimmyB

답변

1

을 이미 내 문제에 대한 해결책을 찾았습니다. 나는 경로를

Join<Player, PlayerTeam> playerTeamJoin = root.join(Player_.playerTeam); 
Join<PlayerTeam, PlayerTeamAssignment> playerTeamAssignments = root.join(PlayerTeam_.playerTeamAssignments); 
Path managerPath = ((Path) playerTeamAssignments.as(ManagerAssignment.class)).get(ManagerAssignment_.manager)); 

을 사용했다 당신은 술어 예를 들면 사용할 수 있습니다 :

Predicate predicate = cb.equal(managerPath.get(Manager_.globalId), managerId);