2012-04-18 14 views
5

Estoy tratando de usar Hibernate para recuperar aproximadamente 100 millones de filas de una tabla. Tengo un elemento de entidad persistente que contiene una colección de tarifas dentro (otra entidad persistente). Dado que I será iterar sobre el resultado y acceder a las tarifas para cada objeto, quiero buscar con impaciencia las tarifas para evitar el problema n + 1.Buscando colecciones de recolección de Hibernate con ScrollableResults

También debo mencionar que quiero unirme a otra tabla llamada Proveedor (asignación uno a uno pero sin clave externa). Intenté:

String query = "select new " + Order.class.getName() 
      + "(i, p) from Item i left join fetch i.fees f, Provider p where " 
      + "p.factoryId=i.factoryId and p.factoryRef=i.factoryRef"; 

return session.createQuery(query).scroll(); 

Mi clase de orden contiene un campo Proveedor y un campo Artículo. Me sale este error:

Caused by: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list

me gustaría terminar con una lista desplazable de la Orden que contienen Artículo (con las tasas recuperada tempranamente) y proveedor.

Respuesta

1

Este código de SelectClause que provoca el problema:

if (!fromElementsForLoad.contains(origin)) { 
         throw new QueryException(
           "query specified join fetching, but the owner " + 
           "of the fetched association was not present in the select list " + 
           "[" + fromElement.getDisplayText() + "]" 
         ); 

Como se puede ver, cuando se menciona la palabra clave buscar, hibernar comprobaciones para ver si se le pregunta por los padres campo Obtener decorado. fromElementsForLoad.contains(origin)

Probablemente lo hicieron para defenderte de hacer una unión redundante que te costará mucho en rendimiento. Es una buena cosa porque no hay razón para buscar la asociación si nunca la usa.

Creo que en su caso - envolviendo el Item.class en el nuevo Order.class se esconde el hecho de que usted usa el campo de búsqueda fetch decorado en la consulta.

No tengo habilidades de depuración en este momento, así que no puedo validar esto. intente y depure esta fila exacta de SelectClause.class y vea qué elementos contiene la colección fromElementsForLoad.

Si quiere evitar el problema n + 1, le recomiendo que inicialice Order.class después de la consulta. Puede seleccionar solo el artículo y el proveedor.

Si no puede validar esto, llegaré a una computadora adecuada la próxima semana y ampliaré mi respuesta.

+0

Creo que esta respuesta es correcta. Si es así, debería dejar que Hibernate sepa que está obteniendo 'Item's cambiando la consulta para devolver' List' en lugar de construir 'Order':' select i, p from ... '. Luego tendrá que crear el 'Order's manualmente. –

0

Intente eliminar el left join fetch i.fees f y realice la búsqueda con ganas en la asignación.

Cuestiones relacionadas