Tengo la siguiente consulta que espero se ejecutan en una única solicitud seleccionar:

@NamedQuery(name=Game.GET_GAME_BY_ID1,
                query = "SELECT g FROM Game g " +
                        "JOIN FETCH g.team1 t1 " +
                        "JOIN FETCH t1.players p1 " +
                        "JOIN FETCH p1.playerSkill skill1 " +
                        "where g.id=:id")

El problema es que todo lo que se obtienen por separado varias consultas.
Quiero que sólo Equipo y jugadores del equipo y de cada jugador habilidades que se obtienen en una sola solicitud. Pero en lugar de eso tengo varias consultas de selección para la obtención de cada equipo, jugador, cada jugador estadísticas y habilidades.

Aquí son entidades que se utilizan con anotaciones de:

Juego Entidad:

public class Game implements Serializable {
    private Integer id;
    private Integer dayNumber;
    private Long date;
    private Integer score1;
    private Integer score2;

    private Team team1;
    private Team team2;

    ....

    @ManyToOne(fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @JoinColumn(name="team_id1")
    public Team getTeam1() {
        return team1;
    }


    public void setTeam1(Team team1) {
        this.team1 = team1;
    }

    //uni directional many to one association to Team
    @ManyToOne(fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @JoinColumn(name="team_id2")
    public Team getTeam2() {
        return team2;
    }


    public void setTeam2(Team team2) {
        this.team2 = team2;
    }
}

Equipo De Entidad:

public class Team implements Serializable {
    ...
    private Set<Player> players;
    ...
    @OneToMany(mappedBy="team", targetEntity=Player.class, fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @Fetch(FetchMode.JOIN)
    @OrderBy(value="batOrder, pitRotationNumber ASC")
    public Set<Player> getPlayers() {
        return players;
    }


    public void setPlayers(Set<Player> players) {
        this.players = players;
    }
}

Jugador Entidad:

public class Player implements Serializable {
    private PlayerStat playerStats;
    private PlayerSkill playerSkill;
    ...
    @OneToOne(mappedBy="player", cascade=CascadeType.ALL)
    @Fetch(FetchMode.JOIN)
    public PlayerStat getPlayerStats() {
        return this.playerStats;
    }

    public void setPlayerStats(PlayerStat playerStats) {
        this.PlayerStats = playerStats;
    }

    ...

    @OneToOne(mappedBy="player", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @Fetch(FetchMode.JOIN)
    public PlayerSkill getPlayerSkill() {
        return this.playerSkill;
    }

    public void setPlayerSkill(PlayerSkill playerSkill) {
        this.playerSkill = playerSkill;
    }
}

Podría apuntar en los errores cometidos?
Necesito una consulta select para cargar el juego, los equipos, los jugadores del equipo y de cada una de las habilidades del jugador.

EDIT 1:
aquí es postgresql registro (una parte de ella), puro consultas sql:
http://pastebin.com/Fbsvmep6

Original de los nombres de las tablas se ha cambiado en esta pregunta por la sencillez, la
El juego es GamelistLeague, Equipo de TeamInfo, y hay BatterStats y PitcherStats en lugar de uno PlayerStat

La primera consulta de los registros es la que se muestra en esta pregunta, por encima de (nombre de la consulta) que, si ejecuto directamente en la base de datos, devuelve todo como sea necesario.

Puede usted por favor enviar el SQL que se ejecuta? ¿Qué pasa si se apaga la recuperación perezosa?
por favor, eche un vistazo en editar. Puedo tratar de apagar la recuperación perezosa pero más tarde, a pesar de que la necesito para ser establecido como perezoso para otras consultas que no debe recuperar con entusiasmo a los jugadores.
Hibernate… por lo que la gente inteligente ejecutar estúpido consultas desde el año 2001. Posiblemente el tiempo para deshacerse de la Hibernación peyorativa y cambiar a algo más cercano al metal 🙂
jajaja 😀
Yo sólo quería decir algo a Lance Java. Me voy a la zanja de hibernación y el uso de mybatis. bueno señor es hibernate me hace verdadero estúpido.

OriginalEl autor maximus | 2015-01-14

2 Comentarios

  1. 24

    Usted está experimentando un problema bien conocido, una.k.una. la «N+1 selecciona».
    En breve, la «N+1 selecciona» problema se produce cuando se selecciona un padre de la entidad y de hibernación hará adicional seleccionar para un niño relacionados a los padres con OneToOne. Así que si usted tiene «N» padre-hijo registros en la base de datos, hibernate obtener todos los padres con un select y, a continuación, obtener de cada niño por separado seleccione, haciendo que el total de N+1 selecciona.

    Hay dos enfoques para «N+1» problema en modo de hibernación:

    1. «Join Fetch» todos OneToOne de los niños.

    2. Habilitar la caché de segundo nivel y el uso de @Caché de anotación en el OneToOne de los niños.

    Su problema es que no es «join fetch» todos los OneToOne los niños.
    Usted debe «join fetch» todos ellos, incluyendo el transitiva niños (entidades de referencia a partir de los propios niños, o dentro de la colección).

    Hacer OneToOne perezoso (porque su ansiosos por defecto) es sólo una solución parcial, porque hibernate hacer un select para sólo un niño cuando usted tener acceso a algunos de captador en el niño, pero en el largo plazo, se sigue que todas las N selecciona.

    también es una buena opción , cuando se trabaja con perezoso recupera. stackoverflow.com/questions/5975752/…

    OriginalEl autor outdev

  2. 4

    La secundaria consultas provienen de:

    @ManyToOne(fetch=FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    @JoinColumn(name="team_id2")
    public Team getTeam2() {
        return team2;
    }

    Es así, usted necesita:

    1. Hacer todas las asociaciones PEREZOSO. De forma predeterminada, todos los @ManyToOne y @OneToOne asociaciones están ANSIOSOS, así que es mejor tenerlos PEREZOSO y sólo reemplazar el plan de recuperación en una consulta de base.

    2. Quitar el @Fetch(FetchMode.JOIN), que es esencialmente una DESEOSOS de recuperar la directiva. En su caso, no sólo la team2 propiedad es una exageración, pero sus jugadores y sus habilidades.

    Hice como usted sugiere, se quitó toda FetchMode.ÚNETE y añadió PEREZOSO para ellos, pero no he notado dos cambios solamente: 1. el equipo está cargado, pero diferentes, seleccione no hacer, 2. todos los jugadores cargan por separado, sin seleccionar para ellos. Lo cual es bueno, pero para cada jugador todavía carga de estadísticas y habilidades. He comprobado varias veces, no hay GANAS de carga para ellos, y no UNIRSE a fetchMode.
    Usted necesita establecer explícitamente PEREZOSO para OneToOne y ManyToOne demasiado. A continuación, utilice join fetch en su consulta.
    Que debo hacer join fetch incluso si no necesito esas entidades a las que se cargan?
    Usted sólo tiene que UNIRSE a recuperarlos cuando los necesite. Si usted no tiene que cargar, cargar sólo el padre de la entidad. En este escenario, todos los PEREZOSOS asociaciones sólo se inicializa al tiempo de acceso. A menos que el acceso a los PEREZOSOS asociaciones, de que nunca va a desencadenar secundaria selecciona.
    Lo siento, pero parece que todavía no funciona. Hice la prueba solo con esa consulta. Antes no era de carga debido a que puede ser anterior recupera ido correctamente. No estoy seguro. Pero incluso después de cambiar como se mencionó en la respuesta en el código, no siendo un montón de equipo con seleccione solicitar fue a la db.

    OriginalEl autor Vlad Mihalcea

Dejar respuesta

Please enter your comment!
Please enter your name here