1
resposta

Spring Data JPA + Named Query xml

Olá, tenho uma dúvida. É possível utilizar o JPA + Hibernate com o named query xml? Pergunto pois me deparei com um problema em particular ao utilizar essa abordagem e realizar os relacionamentos. Por exemplo:

Dada a Query:

<entity class="UsuarioDto">
        <named-native-query name="User.findPermissions" result-class="UsuarioDto">
            <query>
            <![CDATA[
SELECT DISTINCT
                u.id AS cdi_id,
                u.DssLogin AS dss_login,
                u.DssEmail AS dss_email,
                u.CdiMatricula AS cdi_matricula,
                P.DssNomeCorporativo AS dss_nome,
                u.DtdCriacao AS dtd_criacao,
                u.dtdAdmissao AS dtd_admissao,
                u.FlAtivo AS dss_ativo,
                EG.CdiEstrutura AS cdi_estrutura,
                EG.CdiHierarquia AS cdi_CodEstrutura,
                EG.DtdInicio AS dtd_Inicio,
                EG.DtdFim AS dtd_fim,
                T.CdiPermissao AS cdi_permissao,
                T.DssPermissao AS cdi_dss_permissao
            FROM TbUsuario U
                INNER JOIN tbPessoa P ON (p.PHV_CdiMatricula = U.USU_CdiMatricula)
                LEFT JOIN TbEstruturaGerencial EG ON (EG.EGE_CdiUsuario = U.USU_CdiUsuario)
                INNER JOIN TbHierarquia H ON (H.HIE_CdiHierarquia = EG.EGE_CdiHierarquia)
                LEFT JOIN TbUsuarioxTransacao UT ON (UT.UST_CdiUsuario = U.USU_CdiUsuario)
                INNER JOIN tbTransacao T ON (T.TRA_CdiPermissao = u.USU_CdiUsuario)
                WHERE U.USU_CdiUsuario = 5
                 ]]>
            </query>
        </named-native-query>
    </entity>

Ela me retorna 3 resultados. Minha entidade está dessa maneira:

public class UsuarioDto {

    private String dtdCriacao;

    //@Transient
    @OneToMany(mappedBy = "usuario", fetch = FetchType.LAZY)
    private List<TransacaoDto> dssPermissoes;

    //@Transient
    @OneToMany(mappedBy = "usuario", fetch = FetchType.LAZY)
    private List<EstruturaDto> estruturas;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long cdiId;

    private String dssLogin;

    private String dssEmail;

    private String dssNome;

    private Integer cdiMatricula;

Ocorre que o Hibernate tenta sempre executar uma seguna consulta para esses relacionamentos e o @transient não carrega essas entidades. Existe alguma meneira de trabalhar com o xml e mapear as entidades de maneira que elas sejam carregadas sem que o Hibernate efetue uma nova consulta ?

Hibernate: 
    select
        dsstransaca0_.usu_cdi_usuario as usu_cdi_4_7_0_,
        dsstransaca0_.cdi_permissao as cdi_perm1_7_0_,
        dsstransaca0_.cdi_permissao as cdi_perm1_7_1_,
        dsstransaca0_.dss_perfil_atrelado as dss_perf2_7_1_,
        dsstransaca0_.dss_permissao as dss_perm3_7_1_,
        dsstransaca0_.usu_cdi_usuario as usu_cdi_4_7_1_ 
    from
        tb_transacao dsstransaca0_ 
    where
        dsstransaca0_.usu_cdi_usuario=?
1 resposta

Oii, Alexandre! Tudo bem?

Sim, é possível. Como sugestão você pode usar o @Fetch(FetchType.EAGER) nas propriedades dssPermissoes e estruturas da classe UsuarioDto, o Hibernate carrega as entidades relacionadas junto com a entidade principal na consulta inicial, evitando consultas adicionais. Outra opção é usar a cláusula JOIN FETCH na named query XML para carregar as entidades relacionadas na consulta inicial, proporcionando mais controle sobre como o join é realizado. Além disso, a anotação @BatchSize pode otimizar o carregamento de um grande número de entidades relacionadas, especificando o tamanho do lote em que serão carregadas. Essas abordagens ajudam a evitar consultas adicionais e melhorar o desempenho do carregamento de dados relacionados.

Reuni alguns links para você poder colaborar com os seus estudos sobre esse tema:

Espero ter ajudado. Qualquer dúvida, conte conosco.

Abraço!