Problema es que tengo dos bolsas en mi entidad que me gustaría mostrar en mi interfaz jsf (Spring en la parte posterior, por lo que no hay carga diferida). Así que tengo a buscar ansiosamente a mostrar la información en una lista como esta:Hibernate fetch join -> no se puede obtener varias bolsas
- Punto 1 (etiqueta 1, etiqueta 2) (Tag1 ... Tag n)
- Punto 2 (Label 3, Etiqueta 4) (Tag1 ... Tag n)
Poner ambas listas en entredicho no funcionó. Así que probé suerte con una unión fetch. Me permitió buscar una lista, pero cuando agregué la segunda lista, recibí el error conocido de "no puedo buscar varias bolsas".
¿Puede Hibernate manejar dos fetch joins en una consulta?
public class PointOfInterest
@OneToMany(mappedBy="poi")
private List<PointOfInterestLabel> labels = new ArrayList<PointOfInterestLabel>();
@ManyToMany
private List<Tag> tags = new ArrayList<Tag>();
Mi fetch unirse:
SELECT DISTINCT p from PointOfInterest p
left join fetch p.labels
left join fetch p.tags WHERE p.figure = :figure
En el inicio de la creación de mi fábrica de hibernación falla con:
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:94)
at org.hibernate.loader.hql.QueryLoader.<init>(QueryLoader.java:123)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98)
at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:557)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:422)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
... 55 more
Gracias! Por el momento lo reemplacé con Set, pero creo que voy a refactorizar la interfaz mañana y mostrar menos información. ¡Gracias por la respuesta! ¿Cómo lo resolverías cuando no tienes alcance de persistencia en tu interfaz? ¿Utiliza objetos de transferencia de datos integrados en el DAO en lugar de entidades extraídas? Heredé el proyecto y no tengo permitido hacer grandes cambios de diseño, ni puedo cambiarlo a j2ee. : -/ – mkuff
Puede desactivar la carga diferida, lo cual es malo para el rendimiento. Esto recoge las bolsas de inmediato por consultas separadas. También puede acceder a las bolsas (por ejemplo, tamaño) para forzar la carga. La solución perfecta es crear la sesión fuera del dao y guardarla para una transacción comercial completa. (Crear una sesión en cada llamada al dao se llama sesión-por-llamada y es un antipatrón). –
Así que realmente este es un problema de captura 22: si no usas búsqueda de unión, obtienes n + 1 problema o excepción de inicialización perezosa. La sesión fuera de dao es un truco, en primer lugar porque no está cerca del contrato de JPA y, en segundo lugar, porque es difícilmente controlable, ya que no debe hacer suposiciones sobre la vida de una entidad en el momento en que la crea. Puede abarcar varias solicitudes, no necesariamente http. – Deroude