usar sistema registro query modificar insertar imprimir eliminar ejemplo con como buscar apuntes java hibernate jpa ejbql

sistema - query hibernate java



Hibernate(JPA) cómo hacer una consulta entusiasta, cargando todos los objetos secundarios (7)

Si el problema es solo LazyInitializationExceptions, puede evitarlo agregando un OpenSessionInViewFilter.
Esto permitirá que los objetos se carguen en la vista, pero no ayudará con el problema de velocidad.

<filter> <filter-name>hibernateFilter</filter-name> <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class> </filter> <filter-mapping> <filter-name>hibernateFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

En relación con mi pregunta anterior , quiero asegurarme de que todos los objetos secundarios se carguen ya que tengo varios hilos que pueden necesitar acceder a los datos (y así evitar las excepciones de carga diferida). Entiendo que la forma de hacerlo es usar la palabra clave "fetch" en la consulta (EJB QL). Me gusta esto:

select distinct o from Order o left join fetch o.orderLines

Suponiendo un modelo con una clase de Order que tiene un conjunto de OrderLines en él.

Mi pregunta es que la palabra clave "distinta" parece ser necesaria, ya que de lo contrario parece que recibo un Order para cada línea de Order . ¿Estoy haciendo lo correcto?

Quizás, lo que es más importante, ¿hay alguna forma de incorporar todos los objetos secundarios, sin importar cuán profundo sea? Tenemos alrededor de 10-15 clases y para el servidor necesitaremos todo cargado ... Estaba evitando usar FetchType.EAGER ya que eso significa que siempre está ansioso y, en particular, la interfaz web carga todo, pero tal vez ese sea el camino a seguir - ¿Es eso lo que haces? Me parece recordar que intentamos esto antes y luego obtener páginas web realmente lentas, pero ¿quizás eso significa que deberíamos usar un caché de segundo nivel?


Cambiar la anotación es una mala idea IMO. Como no se puede cambiar a perezoso en tiempo de ejecución. Mejor hacer que todo sea flojo, y buscar según sea necesario.

No estoy seguro de entender tu problema sin mapeos. La búsqueda de unir a la izquierda debería ser todo lo que necesita para el caso de uso que describe. Por supuesto, recibirá un pedido por cada línea de pedido si orderline tiene un pedido como su principal.


Es posible que pueda hacer algo así utilizando una consulta de criterios (independientes) y estableciendo el modo de búsqueda. P.ej,

Session s = ((HibernateEntityManager) em).getSession().getSessionFactory().openSession(); DetachedCriteria dc = DetachedCriteria.forClass(MyEntity.class).add(Expression.idEq(id)); dc.setFetchMode("innerTable", FetchMode.JOIN); Criteria c = dc.getExecutableCriteria(s); MyEntity a = (MyEntity)c.uniqueResult();


Eso solo funcionaría para las relaciones de ManyToOne y para ellos @ManyToOne (fetch = FetchType.EAGER) probablemente sea apropiado.

No se recomienda obtener más de una relación OneToMany con entusiasmo y / o no funciona, como se puede leer en el enlace publicado por Jeremy. Solo piense en la declaración SQL que se necesitaría para hacer una búsqueda así ...



Lo que he hecho es refactorizar el código para mantener un mapa de objetos para los administradores de entidades y cada vez que necesito actualizar, cierro el viejo administrador de entidades para el objeto y abro uno nuevo. Utilicé la consulta anterior sin la búsqueda, ya que eso es demasiado profundo para mis necesidades, simplemente haciendo uniones simples en OrderLines, la búsqueda hace que sea aún más profundo.

Hay solo unos pocos objetos para los que necesito esto, alrededor de 20, así que creo que la sobrecarga de recursos en tener 20 administradores de entidades abiertos no es un problema, aunque los DBA pueden tener una visión diferente cuando esto se activa ...

También volví a trabajar las cosas para que el trabajo db esté en el hilo principal y tenga el administrador de entidades.

Chris


¿Has probado con un transformador de resultados? Si utiliza las consultas de Criteria, puede aplicar un transformador de resultados (aunque hay algunos problemas con la paginación y el transformador de resultados ):

Criteria c = ((Session)em.getDelegate()).createCriteria(Order.class); c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); c.list();

em.getDelegate() es un truco que solo funciona si está utilizando hibernate.

Quizás, lo que es más importante, ¿hay alguna forma de incorporar todos los objetos secundarios, sin importar cuán profundo sea? Tenemos alrededor de 10-15 clases y para el servidor necesitaremos todo cargado ... Estaba evitando usar FetchType.EAGER ya que eso significa que siempre está ansioso y, en particular, la interfaz web carga todo, pero tal vez ese sea el camino a seguir - ¿Es eso lo que haces? Me parece recordar que intentamos esto antes y luego obtener páginas web realmente lentas, pero ¿quizás eso significa que deberíamos usar un caché de segundo nivel?

Si todavía está interesado, respondí una pregunta similar en este hilo sobre cómo serializar las colecciones de hibernación .

Básicamente, utilizas una utilidad llamada dozer que mapea frijoles en otros frijoles, y al hacerlo desencadenas todas tus cargas perezosas. Como se puede imaginar, esto funciona mejor si todas las colecciones se recogen con entusiasmo.