2009-08-12 8 views
6

Al realizar una consulta con NHibernate, parece que no respeta el tamaño del lote si se establece en más de los resultados realmente devueltos.nhibernate alterna el tamaño del lote

Estoy utilizando la última versión de NHibernate 2.1.0.4000 y la GA de Linq a NHibernate. Tengo una estructura de objeto similar a la Orden que tiene una colección de OrderLines. Los OrderLines se han definido como una bolsa con el siguiente código XML:

<bag name="OrderLines" access="field.camelcase" table="MyDatabase.OrderLines" lazy="true" batch-size="50"> 
    <key column="OrderId"/> 
    <one-to-many class="OrderLine"/> 
</bag> 

Si la consulta para pedidos y obtener 50 resultados de vuelta se selecciona correctamente todos los OrderLines en una sola consulta, pero si consigo menos de 50 resultados de vuelta no parece respetar el tamaño de lote definido.

E.g. Si obtengo 40 resultados en lugar de 50 si realizo 3 consultas con un tamaño de lote de 25, 12 y 3

que parece que está tratando de adivinar el tamaño de lote correcto para usar (es decir, hace 1/2 del lote primero el tamaño, luego 1/2 del resto, etc.). Esperaría que realice un tamaño de lote de 50 todo el tiempo y si hay menos, haga el tamaño del lote tan grande como sea posible, en este caso un tamaño de lote de 40.

¿Cómo puedo lograr que NHibernate respete? el tamaño del lote que he definido en todos los casos?

Respuesta

10

Estaba tropezando con el mismo comportamiento extraño. Descubrí que las personas tropezaban con lo mismo en Hibernate (Java) también.

El comportamiento se documenta aquí para Hibernate:

http://opensource.atlassian.com/projects/hibernate/browse/HB-1457
https://forum.hibernate.org/viewtopic.php?p=2233747#2233747
https://forum.hibernate.org/viewtopic.php?p=2422139

supongo que este comportamiento es portado directamente de hibernación.

En resumen:
sólo hay unas pocas sentencias SQL para lotes fechting preparado por Hibernate. Cada uno con un tamaño de lote fijo que define el recuento de parámetros en la cláusula IN. Hibernate luego utiliza estas declaraciones preparadas para satisfacer la carga por lotes. El número que especifica como tamaño de lote en el archivo de asignación, solo define el máximo. tamaño del lote que puede ocurrir

Por ejemplo dado el tamaño del lote = 1000. Si tiene 200 entidades padre y desea cargar sus colecciones secundarias, nHibernate decide usar 4 instrucciones: una con 125, 62, 10 y 3 parámetros en la cláusula IN (sumando hasta 200).

Sin embargo, si solo tiene 125 entidades padre, entonces hibernate decide usar solo una declaración, la que tiene 125 parámetros.

(Los números de arriba son mis observaciones en NH 2.1)

La razón detrás de esto: (de acuerdo con el foro de discusión relacionado)
La preocupación por el impacto en el rendimiento negativo de la creación de muchos PreparedStatements diferentes cuando las el tamaño máximo del lote es grande. (PreparedStatements es una construcción de Java, me pregunto si esta preocupación de rendimiento es igualmente válida para.NET)

Cuestiones relacionadas