1
resposta

EAGER seria a melhor solução?

Fala professor, beleza?

Na nossa entidade Funcionario, temos o atributo unidades com o mapeamento:

    @Fetch(FetchMode.SELECT)
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "funcionarios_unidades",joinColumns = {
            @JoinColumn(name = "fk_funcionario")},
    inverseJoinColumns = { @JoinColumn(name = "fk_unidade")})
    private List<Unidade> unidades;

Porém, pelo que aprendi nos cursos anteriores, essa não seria uma boa solução, visto que a lista de unidades estaria sendo carregada mesmo que eu realizasse uma consulta somente a atributos do funcionário.

Diante disso, a melhor solução seria deixá-la com o fecth sendo LAZY, e caso seja necessário alguma consulta ao atributo unidades faríamos uma query planejada?

Acredito que o senhor tenha usado essa forma por questões didáticas, pois não precisamos criar query planejada e somente usar o próprio find para buscar um funcionário, por exemplo.

Consulta buscar funcionário por nome realizada com o FetchType.EAGER

Hibernate: select funcionari0_.id as id1_1_, funcionari0_.cargo_id as cargo_id6_1_, funcionari0_.cpf as cpf2_1_, funcionari0_.data_contratacao as data_con3_1_, funcionari0_.nome as nome4_1_, funcionari0_.salario as salario5_1_ from funcionarios funcionari0_ where funcionari0_.nome=?
Hibernate: select cargo0_.id as id1_0_0_, cargo0_.descricao as descrica2_0_0_ from cargos cargo0_ where cargo0_.id=?
Hibernate: select unidades0_.fk_funcionario as fk_funci1_2_0_, unidades0_.fk_unidade as fk_unida2_2_0_, unidade1_.id as id1_3_1_, unidade1_.descricao as descrica2_3_1_, unidade1_.endereco as endereco3_3_1_ from funcionarios_unidades unidades0_ inner join unidades unidade1_ on unidades0_.fk_unidade=unidade1_.id where unidades0_.fk_funcionario=?
Hibernate: select funcionari0_.fk_unidade as fk_unida2_2_0_, funcionari0_.fk_funcionario as fk_funci1_2_0_, funcionari1_.id as id1_1_1_, funcionari1_.cargo_id as cargo_id6_1_1_, funcionari1_.cpf as cpf2_1_1_, funcionari1_.data_contratacao as data_con3_1_1_, funcionari1_.nome as nome4_1_1_, funcionari1_.salario as salario5_1_1_, cargo2_.id as id1_0_2_, cargo2_.descricao as descrica2_0_2_ from funcionarios_unidades funcionari0_ inner join funcionarios funcionari1_ on funcionari0_.fk_funcionario=funcionari1_.id inner join cargos cargo2_ on funcionari1_.cargo_id=cargo2_.id where funcionari0_.fk_unidade=?
Hibernate: select unidades0_.fk_funcionario as fk_funci1_2_0_, unidades0_.fk_unidade as fk_unida2_2_0_, unidade1_.id as id1_3_1_, unidade1_.descricao as descrica2_3_1_, unidade1_.endereco as endereco3_3_1_ from funcionarios_unidades unidades0_ inner join unidades unidade1_ on unidades0_.fk_unidade=unidade1_.id where unidades0_.fk_funcionario=?

Consulta buscar funcionário por nome realizada com o FetchType.LAZY

Hibernate: select funcionari0_.id as id1_1_, funcionari0_.cargo_id as cargo_id6_1_, funcionari0_.cpf as cpf2_1_, funcionari0_.data_contratacao as data_con3_1_, funcionari0_.nome as nome4_1_, funcionari0_.salario as salario5_1_ from funcionarios funcionari0_ where funcionari0_.nome=?
Hibernate: select cargo0_.id as id1_0_0_, cargo0_.descricao as descrica2_0_0_ from cargos cargo0_ where cargo0_.id=?

A diferença é imensa.

1 resposta

Olá Ayrton, tudo bem?

Realmente, você está correto em relação ao uso do FetchType.EAGER. Quando utilizamos esse tipo de carregamento, todas as entidades relacionadas são carregadas junto com a entidade principal, mesmo que não precisemos delas naquele momento. Isso pode causar um grande impacto no desempenho da aplicação.

A solução que você sugeriu é uma boa prática. Utilizar o FetchType.LAZY e fazer uma consulta planejada quando necessário é uma forma mais eficiente de carregar as entidades relacionadas, pois elas só serão carregadas quando realmente precisarmos delas.

Lembrando que essa é uma questão que deve ser avaliada caso a caso, dependendo da necessidade da aplicação e do volume de dados envolvidos.

Espero ter ajudado e bons estudos!