2012-08-07 10 views
6

Mi problema es muy simple, pero no sé cómo hacer Hibernate de la manera que quiero: - tabla MainTable tengo Many-2-One con ParentTable (con 100 filas). punto MainTable a m = 26 filas de 100 filas en ParentTableHibernate genera m + 1 consultas en Many-to-one

@ManyToOne(fetch = FetchType.EAGER) 
@JoinColumn(name = "PARENT_ID") 
@Fetch(FetchMode.JOIN) 

Cuando simplemente consulta "de MainTable"

que va a generar 26 + 1 consultas

Cuando trazo las consultas, el La primera consulta solo carga PARENT_ID utilizada por 26 consultas posteriores. Supongo que debe tener la forma de cargar todo el PARENT_TABLE en la consulta primero ..

Por favor, ayudar asumiendo que:

  • FetchType.EAGER es una NECESIDAD
  • Usando de MainTable mt combinación izquierda ir a buscar los padres mt.parent está bien, pero tenemos muchas asociación
+0

Evitar N + 1 selecciona el problema: http://www.realsolve.co.uk/site/tech/hib-tip-pitfall.php?name=n1selects http://stackoverflow.com/questions/97197/what -is-the-n1-select-problem –

+0

@Pangea: Gracias pero aquí algunos comentarios: 1) Usar fetch join es bueno, pero tenemos cerca de diez Parent table. Esa será la última solución 2) Queremos que algo similar a Subselect busque en One-2-Many, de modo que 1 consulta para MainTable, 1 más para la tabla relacionada –

+0

@Fetch (FetchMode.JOIN) y @Fetch (FetchMode.SELECT) no dar ninguna diferencia en absoluto! o_0 –

Respuesta

3
// Annotate ParentTable Persistance class file with a batch Size 
@BatchSize(size=100) 
class ParentTable{ 
    .. 
} 

@ManyToOne 
@JoinColumn(name = "PARENT_ID") 

Esto reducirá el número de consultas en n/100 + 1.

La razón de este problema es que, el hibernate obtendrá los datos en modo perezoso internamente, (No estoy hablando del FetchMode.Lazy). El modo Lazy se puede excluir utilizando FetchMode.SUBSELECT, que se aplica solo para colecciones. Cuando se trata de @ManyToOne, puede seleccionar un batch de datos, especificando el batchSize.

una breve descripcion de Fetch startegies

FetchMode.SUBSELECT

una consulta para los padres, una consulta para la tabla relacionada. Aplicable solo para el marco de Colecciones. Solo 2 consultas disparadas.

FetchMode.SELECT

una consulta para Padres, N consultas para el niño.

FetchMode.JOIN

una consulta para Padres, N consultas para el niño, pero la recuperación de la base de datos tienen lugar por adelantado en unirse.

FetchType.Batch

una consulta para padres y n/batchSize + 1 número de consultas disparados.


Hay dos tipos de ir a buscar, en función de cuándo las consultas deben ser ejecutados.

FetchType.EAGER:

Las consultas se disparan al instante.

FetchType.LAZY:

Las consultas se disparan cuando se accede al objeto secundario. Por lo tanto, el número de de las consultas ejecutadas dependerá de la cantidad de objetos secundarios accedidos.

How the Fetch Strategies work is better explained here.

Cuestiones relacionadas