2016-10-10 3 views
0

Gibt es eine Möglichkeit, Klasse Player mit Manager in der Hierarchie wie folgt unter Verwendung Criteria API beizutreten? Ich möchte alle Spieler mit Manager angegebenen ID in meine DAO und so etwas versucht zu finden:JPA 2 Kriterien beitreten mit abstrakten Sammlung

Abfrage:

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); 

Klassenhierarchie:

@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

Ich denke, Ihr Datenmodell eine Überarbeitung benötigen. – JimmyB

+0

Danke für die Antwort. Die Sache ist, dass es nicht geändert werden kann. Klassennamen werden für die Fragezwecke vereinfacht - tatsächlich stellen sie eine etwas kompliziertere Struktur dar – Macieyo

+0

Beachten Sie, dass 'PlayerTeamAssignment' kein Feld' manager' hat. Warum starten Sie Ihre Abfrage nicht von 'ManagerAssignment', also' SELECT ... FROM ManagerAssignment JOIN ... '? – JimmyB

Antwort

1

Ich habe bereits eine Lösung für mein Problem gefunden. Ich hatte Pfad

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)); 

verwenden und Sie es zum Beispiel in Prädikat verwenden können:

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