tutorial paneles example create java hibernate objectinstantiation

java - paneles - Consulta de hibernación simple que regresa muy lentamente



table swing java (7)

Agregar un constructor con todos los atributos de la clase hizo el truco, ahora los tiempos de ejecución son 70 ms para la consulta de hibernación. Anteriormente, la clase solo tenía un constructor predeterminado sin argumentos y un constructor con el argumento de identificación de la entidad.

Tengo la siguiente consulta de hibernación:

Query query = session.createQuery("from MyHibernateClass"); List<MyHibernateClass> result = query.list();// executes in 7000ms

Al registrar el sql que se está ejecutando en MySQL veo

select myhibernat0_.myFirstColumn as myfirstcolumn92_, myhibernat0_.mySecondColumn as mysecondcolumn92_, myhibernat0_.mythirdcolumn as mythirdcolumn92_, myhibernat0_.myFourthColumn as myfourthcolumn92_ from MyHibernateClass myhibernat0_ where (1=1);

Al medir el código java en el jvm en un pequeño conjunto de datos de 3500 filas en la tabla de la base de datos MyHibernateClass, esto lleva unos 7000 ms.

Si, por otro lado, uso jdbc directo de la siguiente manera:

Statement statement = session.connection().createStatement(); ResultSet rs = statement.executeQuery("select * from MyHibernateClass");// 7ms List<MyHibernateClass> result = convert(rs);// executes in 20ms

Veo el mismo SQL ingresando a la base de datos, pero ahora el tiempo empleado en el código de Java en el jvm es de 7 ms.

MyHibernateClass es una clase de bean Java simple con getters y setters, no utilizo ningún conversor de resultados especial, como se puede ver en el ejemplo. Solo necesito una instancia de solo lectura de la clase y no es necesario adjuntarla a la sesión de hibernación.

Preferiría utilizar la versión de hibernación pero no puedo aceptar los tiempos de ejecución.

Información agregada : después de agregar el registro de hibernación veo

[2011-07-07 14:26:26,643]DEBUG [main] [logid: ] - org.hibernate.jdbc.AbstractBatcher.logOpenResults(AbstractBatcher.java:426) - about to open ResultSet (open ResultSets: 0, globally: 0)

seguido de 3500 de las siguientes declaraciones de registro

[2011-07-07 14:26:26,649]DEBUG [main] [logid: ] - org.hibernate.loader.Loader.getRow(Loader.java:1197) - result row: EntityKey[com.mycom.MyHibernateClass#1]

seguido de 3500 declaraciones de registro como

[2011-07-07 14:27:06,789]DEBUG [main] [logid: ] - org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:130) - resolving associations for [com.mycom.MyHibernateClass#1] [2011-07-07 14:27:06,792]DEBUG [main] [logid: ] - org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:226) - done materializing entity [com.mycom.MyHibernateClass#1]

¿Qué significa esto?

¿Qué está haciendo Hibernate en la primera implementación? ¿Cómo puedo averiguarlo?


En base a la nueva información, sentí que debía proporcionar otra respuesta. La diferencia parece ser que tiene una asociación uno a muchos especificada para una propiedad Lista o Establecer en su bean.

Probablemente esté especificando que lazy=false que desactivará la carga diferida. Con la carga diferida desactivada, obtendrá todos los registros asociados para cada entidad MyHibernateClass y esta es la razón por la que tarda tanto tiempo en ejecutarse.

Intente establecer lazy=true y esto funcionará mucho más rápido y luego solo recuperará las entidades asociadas cuando las solicite explícitamente desde la entidad.


Me tomó 10 segundos ejecutar una consulta de selección simple todo antes de descubrir que la etiqueta DOCTYPE está escrita incorrectamente en hibernate.cfg.xml y *mapping object*.hbm.class

Asegúrese de que hibernate.cfg.xml comience con

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

Y mapeando xml.class con

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

Ahora me llevó 1-2 segundos ejecutar cualquier consulta.


Sé que esta es una vieja pregunta, pero esto es lo que me solucionó ...

En su hibernate.cfg.xml, asegúrese de tener el DOCTYPE correcto ... debería ser el siguiente:

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">


Sé que este hilo es viejo, pero para actualizar me encontré con el mismo problema pero con SQL Server y resulta que ese SQL que Hibernate está imprimiendo y SQL Sent usando el controlador es diferente. El uso de MSSQL Driver de forma predeterminada envía las consultas como procedimientos almacenados como llamadas RPC porque el controlador intenta optimizar el plan de consulta para estándares MSSQL, por lo que envía las consultas algo así como

Consulta de Hibernate:

select c.col1,c.col2 from customer c where c.name like @param1 and c.country like @param2

Consulta enviada del controlador real:

@param1=somevalue, @param2=somevalue declar sp .... select c.col1,c.col2 from customer c where c.name like @param1 and c.country like @param2 go

Nota: Esta consulta que obtuve a través de la herramienta de análisis de SQL directamente escuchando en DB

Resulta que las optimizaciones de sp_exec en el MSSQL tienden a producir buenos planes de consulta que se almacenan en caché, pero esto daría como resultado el ''olfateo de parámetros'' para saber más sobre este problema que se lee aquí ...

Para superar esto, tenía las siguientes opciones:

  1. Cambiar mi HQL a consultas nativas y agregar OPCIÓN RECOMPLE PARA ALGÚN PARÁMETRO

  2. Use los valores de consulta directa en lugar de las declaraciones preparadas, de modo que no habrá traducción para los valores de param y las consultas no se modificarán como procedimientos almacenados por el controlador.

  3. Cambie la configuración del controlador para no enviar los procedimientos almacenados (esto sigue siendo malo porque ahora los planes de consulta en el servidor MSSQL serán específicos de esta consulta, esto es lo mismo que Opción: 2 pero fuera del código)

No quería usar las OPCIONES 1 y 2, ya que eso elimina el propósito de usar marcos ORM y termino usando la OPCIÓN 3 por ahora

Así que cambié la URL de JDBC para enviar la opción prepareStatement = false

Después de configurar esto, tuve un problema más al enviar la consulta como

Select * from customer c where c.name like **N**''somename'' and c.country=**N**''somevalue''

Aquí hay un prefijo antes de los valores que indica que para convertir el esquema de codificación, entonces deshabilito la url JDBC para sendUnicode = false

Esto todo lo que hice en las opciones del controlador JTDS. En lo que a mí respecta, ahora la aplicación está en funcionamiento rápidamente. También introduje los cachés de segundo nivel para almacenarlos en caché durante un tiempo.

Espero que esto ayude a alguien, si tienes alguna sugerencia, por favor avísame.


Si utiliza Log4j en su aplicación, puede establecer una variedad de opciones de registro específicas para Hibernate para obtener una mejor idea de lo que ocurre detrás de escena en Hibernate.

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-logging

Mi suposición es que este es el tiempo de carga inicial típico que se produce cuando se llama por primera vez a una consulta HQL en una aplicación. Las consultas subsiguientes de HQL deberían ser notablemente más rápidas después de esta primera.


Tuve un incidente en el que mi aplicación siempre usaba cada fila en el conjunto de resultados de una consulta. Encontré un aumento de 40 veces en la velocidad configurando el tamaño de mi búsqueda usando el método setFetchSize a continuación. (La mejora del rendimiento incluye la adición de la consulta de conteo).

Long count = getStoreCount(customerId); Query query = session.getNamedQuery("hqlGetStoresByCustomerId") .setString("i_customerid",customerId) .setFetchSize(count.intValue());

Tenga cuidado al hacer esto; mi conjunto de datos tenía alrededor de 100 filas, y tenía un alcance de la vida de una solicitud web. Si tiene conjuntos de datos más grandes, comerá Java Heap mientras dure la existencia de esos datos, antes de devolverlos al Java Heap.