2009-02-09 11 views
5

derecha - Quiero eliminar (por ejemplo) 1.000.000 registros de una base de datos. Esto lleva mucho tiempo -> la transacción expira y falla. Entonces, los borro en lotes, digamos 25000 registros por transacción. Usando la cláusula de límite en MySQL o ROWNUM en Oracle. Genial, esto funciona.lotes supresión/purga de registros a través de Java ORM

quiero hacer esto de una manera independiente de la base de datos. Y a partir de una base de código Java existente que utiliza JPA/Hibernate.

Fuera de suerte. JPA Query.setMaxResults y setFirstResult no tienen efecto para escribir 'consultas' (por ejemplo, eliminar). Seleccionar muchas entidades en la memoria para eliminarlas individualmente es muy lento y tonto, diría yo.

lo tanto, utilizar una consulta nativa y gestionar la cláusula de 'límite' en el código de la aplicación. Sería bueno para encapsular esta cláusula en orm.xml pero ... "Anotaciones de Hibernate 3.2 no es compatible con actualización masiva/elimina un uso de consultas nativas". - http://opensource.atlassian.com/projects/hibernate/browse/ANN-469.

Me imagino que este es un problema común. ¿Alguien obtuvo una mejor solución independiente de base de datos?

Respuesta

0

Los límites en las consultas es una característica específica de la base de datos y no hay un estándar SQL (estoy de acuerdo que debe existir).

Una solución que funciona con la mayoría de las bases de datos está utilizando una vista para agrupar varias tablas en una sola. Cada tabla contiene un subconjunto de los datos (por ejemplo, un día). Esto le permite descartar un subconjunto completo a la vez. Dicho esto, muchas bases de datos tienen problemas para ejecutar UPDATE e INSERT en dicha vista.

Generalmente, usted puede evitar esto mediante la creación de un punto de vista o alias para INSERT/UPDATE; una vista agrupación de búsqueda (lo que apunta a una sola tabla de la "corriente" uno) y.

Algunas bases de datos también ofrecen particiones que son básicamente lo mismo, excepto que puede definir una columna que especifique en qué tabla subyacente debe ir una fila (en INSERTAR). Cuando necesite eliminar un subconjunto, puede colocar/truncar una de las tablas subyacentes.

5

Odio dar una respuesta no constructiva, pero un ORM no está destinado a realizar operaciones masivas en la base de datos. Por lo tanto, parece que su consulta nativa es probablemente la mejor opción para estas operaciones.

También debe asegurarse de que su ORM esté actualizado para reflejar el nuevo estado de la base de datos, de lo contrario, puede experimentar algunas rarezas.

Los ORM son excelentes herramientas para asignar objetos a bases de datos, pero generalmente no son interfaces de bases de datos genéricas.

0

Creo que se puede usar HQL (JPA QL) dirigir las operaciones de DML que pasar por alto el contexto de persistencia y la memoria caché, y ejecutar las sentencias SQL (resultante) directamente:

Query q = session.createQuery("delete YourEntity ye where ye.something like :param"); 
q.setParameter("param", "anything"); 
int deletedEntities = q.executeUpdate(); 
+0

Creo que la pregunta-autor de la pregunta ya lo está haciendo, pero al ver que la eliminación es tan lenta que el tiempo de espera. –

0

q.setMaxResults(int)

.. .sony

+0

El OP ya indicó que lo intentaron sin éxito: "Sin suerte. Consulta de JPA.setMaxResults y setFirstResult no tienen efecto para escribir 'consultas' ... ' – Mac

Cuestiones relacionadas