Pregunta

Hibernate emite esta excepción durante la creación SessionFactory:

  

org.hibernate.loader.MultipleBagFetchException: No se pueden obtener simultáneamente múltiples bolsas

Esta es mi caso de prueba:

Parent.java

@Entity
public Parent {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 // @IndexColumn(name="INDEX_COL") if I had this the problem solve but I retrieve more children than I have, one child is null.
 private List<Child> children;

}

Child.java

@Entity
public Child {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @ManyToOne
 private Parent parent;

}

¿Qué hay de este problema? ¿Qué puedo hacer?


Editar

correcto, el problema que tengo es que otra entidad "padre" está dentro de mis padres, mi comportamiento real es la siguiente:

Parent.java

@Entity
public Parent {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @ManyToOne
 private AntoherParent anotherParent;

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 private List<Child> children;

}

AnotherParent.java

@Entity
public AntoherParent {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 private List<AnotherChild> anotherChildren;

}

Hibernate no lo hace como dos colecciones con FetchType.EAGER, pero esto parece ser un error, no estoy haciendo cosas inusuales ...

Extracción de FetchType.EAGER Parent o AnotherParent resuelve el problema, pero lo necesito, por lo verdadera solución es utilizar @LazyCollection(LazyCollectionOption.FALSE) en lugar de FetchType (gracias a Bozho para la solución).

¿Fue útil?

Solución

creo una versión más reciente de hibernación (con soporte para JPA 2.0) debe manejar esto. Pero por lo demás se puede trabajar en torno al anotar los campos de recolección con:

@LazyCollection(LazyCollectionOption.FALSE)

Recuerde que para quitar el atributo fetchType partir de la anotación @*ToMany.

Pero tenga en cuenta que en la mayoría de los casos, un Set<Child> es más apropiado que List<Child>, así que a menos que realmente necesita un List - go para Set

Otros consejos

Simplemente cambiar de un tipo a List tipo Set.

Añadir una anotación de Hibernate @Fetch-específica de su código:

@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
private List<Child> childs;

Esto debería solucionar el problema, relacionado con la hibernación fallo HHH-1718

Después de probar con cada opción única de describir en este postes y otros, llegó a la conclusión de que la solución del proceso es como sigue.

En cada lugar XToMany @XXXToMany(mappedBy="parent", fetch=FetchType.EAGER) y de forma intermedia después de

@Fetch(value = FetchMode.SUBSELECT)

Esto funcionó para mí

Para solucionarlo simplemente tomar Set en lugar de List para su objeto anidado.

@OneToMany
Set<Your_object> objectList;

y no se olvide de usar fetch=FetchType.EAGER

va a trabajar.

Hay un concepto más CollectionId en Hibernate si desea seguir con la lista única.

He encontrado un buen blog post sobre el comportamiento de Hibernate en este tipo de asignaciones de objetos: http : //blog.eyallupu.com/2010/06/hibernate-exception-simultaneously.html

puede mantener listas de cabina EAGER en APP y añadir a por lo menos uno de ellos la anotación JPA @OrderColumn (con, obviamente, el nombre de un campo a ser pedido). No hay necesidad de anotaciones de hibernación específicos. Pero hay que tener en cuenta que podría crear elementos vacíos en la lista si el campo elegido no tiene los valores a partir de 0

 [...]
 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 @OrderColumn(name="orderIndex")
 private List<Child> children;
 [...]

en niños entonces usted debe agregar el campo orderIndex

La razón por la que recibe esa excepción es que Hibernate podría terminar haciendo un producto cartesiano que es malo para el rendimiento.

Ahora, si bien se puede "arreglar" el problema utilizando Set en lugar de List, no deberías hacer eso porque el producto cartesiano todavía será presentado en las sentencias SQL subyacentes.

Usted es mejor cambiar de FetchType.EAGER a Fetchype.LAZY puesto recuperación temprana es un idea terrible que puede conducir a problemas de rendimiento de aplicaciones críticas .

Si necesita buscar a los entidades secundarias a través de una jerarquía de niveles múltiples, mejor elegir la más interior niño hasta los padres, como se explica en este artículo .

Cuando tiene objetos muy complejos con la colección de saveral no podría ser buena idea tener todos ellos con fetchType Eager, un mejor uso perezoso y cuando realmente se necesita para cargar las colecciones utiliza:. Hibernate.initialize(parent.child) para ir a buscar los datos

Tratamos Set en lugar de Lista y es una pesadilla: cuando se agrega dos nuevos objetos, es igual a () y hashCode () no distinguen los dos! Debido a que no tiene ninguna ID.

herramientas típicas como Eclipse generar ese tipo de código de tablas de bases de datos:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    return result;
}

También puede leer este artículo que explica adecuadamente la forma en mal estado JPA / Hibernate es. Después de leer esto, creo que esta es la última vez que utilizo cualquier ORM en mi vida.

He encontramos también con dominio Driven Design chicos que básicamente dicen ORM son una cosa terrible.

Para mí, el problema fue haber anidado EAGER recuperaciones.

Una solución es establecer los campos anidados a LAZY y utilizar Hibernate.initialize () para cargar el campo anidada (s):

x = session.get(ClassName.class, id);
Hibernate.initialize(x.getNestedField());

Se podría utilizar una nueva anotación para resolver esto:

@XXXToXXX(targetEntity = XXXX.class, fetch = FetchType.LAZY)

De hecho, se ha podido recuperar del valor por defecto es FetchType.LAZY también.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top