Boa tarde galera,
Possuo uma entidade onde tenho um OneToMany:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ass_id")
private int ass_id;
@OneToMany(mappedBy = "ass_id", fetch = FetchType.LAZY)
private List<AssistenciaItem> assistenciaItems;
Só que tenho um datatable em que eu listo todos os itens dessa entidade, porém eu também mostro a quantidade de itens do relacionamento, por exemplo assistenciaItems.size().
Dessa forma eu carrego com Lazy todos os itens do AssistenciaItem, porém eu queria saber qual a melhor prática de eu mostrar todos os itens dessa entidade e também a quantidade do relacionamento realizando somente um COUNT() no banco, ganhando assim performance.
Qualquer dica/opinião é bem vinda.
Muito obrigado. Abraço!
Bom, em questão a carregar a lista não tem muito segredo, busque ela somente quando necessário. não carregue relacionamentos OneToMany quando não há necessidade.
E quanto a mostrar o número de itens, é melhor fazer com count mesmo, a não ser que a lista já esteja carregada.
[quote=Rodrigo Sasaki]Bom, em questão a carregar a lista não tem muito segredo, busque ela somente quando necessário. não carregue relacionamentos OneToMany quando não há necessidade.
E quanto a mostrar o número de itens, é melhor fazer com count mesmo, a não ser que a lista já esteja carregada.[/quote]
A unica forma vai ser eu criar um getQuantidadeItens na entidade que vai fazer um query no banco com COUNT()?
O problema é se eu fizer um if(assistenciaItens == null) { executar query COUNT }, ele vai buscar no banco por ser LAZY.
Outro problema é que se eu listar 100 itens, ele vai fazer 1 query pra trazer todos os itens, e depois mais 1 query pra cada item com um COUNT(), no total vou fazer 101 queries, isso não seria bom, correto?
Eu tinha pensado em algo como criar um atributo na entidade que nao exista no banco como “quantidadeItens” e deixar como Lazy, e depois no meu HQL eu crio um COUNT(item) AS quantidadeItens. Isso não seria possível?
Então, é isso que eu disse.
Se você está em uma situação onde só precisa do número de itens, uma query com COUNT é uma solução melhor.
Se você precisa carregar todos E saber o número de itens, carregue primeiro e veja o tamanho da coleção.
[quote=Rodrigo Sasaki]Então, é isso que eu disse.
Se você está em uma situação onde só precisa do número de itens, uma query com COUNT é uma solução melhor.
Se você precisa carregar todos E saber o número de itens, carregue primeiro e veja o tamanho da coleção.[/quote]
Em qual das coisas que eu citei você quis dizer que foi o que você disse? Foi aquela opção que vai me gerar 101 queries? Ou a outra opção que eu crio um atributo e dou select no meu HQL com o COUNT junto tornando assim somente 1 query?
Se for a segunda coisa que eu disse, você saberia fazer isso?
[quote=faelzindc]
Se você precisa carregar todos E saber o número de itens, carregue primeiro e veja o tamanho da coleção.[/quote]
Em qual das coisas que eu citei você quis dizer que foi o que você disse? Foi aquela opção que vai me gerar 101 queries? Ou a outra opção que eu crio um atributo e dou select no meu HQL com o COUNT junto tornando assim somente 1 query?
Se for a segunda coisa que eu disse, você saberia fazer isso?[/quote]
Mais pra primeira do que para a segunda. Eu não conheço o seu cenário, mas o que eu vejo normalmente é uma query com um COUNT caso só seja necessário buscar o tamanho da lista, sem acessar os seus dados.
Agora se você já tiver a lista carregada, pode simplesmente invocar o método size.
Caso precise armazenar esse tamanho, sem a lista carregada, aí pode ser viável ter um atributo transiente na sua classe, ou até uma variável local. Mais uma vez, como não conheço bem o cenário, estou falando bem por cima
[quote=Rodrigo Sasaki][quote=faelzindc]
Se você precisa carregar todos E saber o número de itens, carregue primeiro e veja o tamanho da coleção.[/quote]
Em qual das coisas que eu citei você quis dizer que foi o que você disse? Foi aquela opção que vai me gerar 101 queries? Ou a outra opção que eu crio um atributo e dou select no meu HQL com o COUNT junto tornando assim somente 1 query?
Se for a segunda coisa que eu disse, você saberia fazer isso?[/quote]
Mais pra primeira do que para a segunda. Eu não conheço o seu cenário, mas o que eu vejo normalmente é uma query com um COUNT caso só seja necessário buscar o tamanho da lista, sem acessar os seus dados.
Agora se você já tiver a lista carregada, pode simplesmente invocar o método size.
Caso precise armazenar esse tamanho, sem a lista carregada, aí pode ser viável ter um atributo transiente na sua classe, ou até uma variável local. Mais uma vez, como não conheço bem o cenário, estou falando bem por cima[/quote]
Então, da primeira forma irei gerar 101 queries, pois tenho uma DataTable que vai listar 100 itens da ASSISTENCIA, e possuo outra tabela que é relacionada com a assistencia que é OneToMany, e que é ASSISTENCIAITENS… Na DataTable vou mostrar as informações da ASSISTENCIA, e a quantidade de itens relacionados na ASSISTENCIAITENS, ou seja, se eu criar um metodo que vai buscar o count, na hora de mostrar os 100 na datatable vai fazer 1 query para cada ASSISTENCIA, que vai me resultar em 101 queries no total.
O que eu gostaria de fazer era criar um atributo transient, e nesse atributo eu carregar a quantidade. Ou seja, na hora que eu busco a lista de ASSISTENCIA, no select ja vai conter o COUNT do relacionamento, assim trazendo tudo de uma vez…
O problema é que não sei fazer essa variavel transient pra trazer o COUNT junto…
Segue a solução da minha dúvida:
Só preciso descobrir agora como acabar com a query N+1 nesse caso 
Obrigado a todos!