Coleção de hibernato inicialmente inicializada por filtro
-
27-09-2019 - |
Pergunta
Isso pode ser uma resposta super fácil, já que tenho certeza de que não é incomum. Eu vejo algumas perguntas semelhantes, mas nada que parece descrever meu problema.
Eu tenho dois objetos: um carro e uma pessoa. Eles estão em um relacionamento muitos para muitos, ou seja, um carro pode pertencer a várias pessoas, e uma pessoa pode possuir vários carros. Car
tem um conjunto preguiçoso de Drivers
:
@ManyToMany(targetEntity=Person.class, fetch=FetchType.LAZY)
private Set<Person> people;
Quero encontrar todos os carros azuis com proprietários com menos de 25 anos:
Criteria foo = persistenceManager.createCriteria(Car.class, "myCarAlias");
Criteria bar = foo.createCriteria("drivers", "myDriverAlias");
//add restrictions on foo and bar for blue and age, respectively
baz = foo.list();
Meu problema é quando eu itero pela lista e ligo getDrivers()
Em cada carro, ele inicializa a coleção e recebe todos os motoristas desse carro. Eu acho que o .list()
Eu corri não define os resultados em cada carro.
Recebo os resultados que espero que eu execute manualmente o SQL Hibernate está gerando, por isso tenho razoavelmente certeza de que os critérios não são o problema.
Eu posso entender por que isso acontece, mas não tenho certeza de como contorná -lo sem itetar sobre cada carro e executar uma consulta para os motoristas em cada um. Eu gostaria de evitar fazer isso, se possível, e apreciaria qualquer conselho.
Desde já, obrigado!
Solução
Você esperava que a coleção de motoristas para cada carro contivesse apenas pessoas que correspondiam aos seus critérios (ou seja, têm mais de 25 anos)? Em outras palavras, você não quer a coleção de motoristas que contêm pessoas com mais de 25 anos?
Se for esse o caso, você precisará usar um resultTransformer (ver Seção 15.4 da documentação do hibernato) porque o hibernato não é pré-filtro antes de devolver os resultados.
Se, no entanto, o problema é que a coleção de motoristas estiver sendo carregada preguiçosa e isso não é desejável, definir o modo de busca (normalmente uso o junção, pois o iirc fetchmode.ager foi predefinado) deve resolver o problema:
baz = persistenceManager.createCriteria(Car.class, "myCarAlias")
.setFetchMode("drivers", FetchMode.JOIN)
// add additional restrictions here
.list();
Outras dicas
Seção 15.5 da documentação do hibernato. Basicamente, você pode definir a estratégia de busca para suas consultas de critérios, o que deve ter precedência sobre a estratégia básica de busca que você definiu para o relacionamento.
o exemplo da documentação
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.setFetchMode("mate", FetchMode.EAGER)
.setFetchMode("kittens", FetchMode.EAGER)
.list();
e a documentaçãohttp://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html