2016-10-10 85 views
0

是否有任何方式使用Criteria API加入具有Manager层次结构的Player类,如下所示: 我想找到与给定ID的管理器中所有玩家在我的DAO,并试图像这样: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);