Pregunta

existe una solución para el lote insertar a través de hibernate en particiones de tabla de postgresql?actualmente estoy recibiendo un error como este...

ERROR org.hibernate.jdbc.AbstractBatcher - Exception executing batch:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
   at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
   at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
   at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68)....

he encontrado este enlace http://lists.jboss.org/pipermail/hibernate-dev/2007-October/002771.html pero no puedo encontrar en cualquier lugar en la web es que este problema se resuelva o cómo se puede obtener alrededor de

¿Fue útil?

Solución

Es posible que desee probar el uso de una costumbre Dosificador mediante el establecimiento de la hibernación.jdbc.factory_class de la propiedad.Asegurarse de hibernación no revise el recuento de actualización de las operaciones por lotes puede solucionar su problema, usted puede lograr que, al hacer de su personalizados Dosificador extender la clase BatchingBatcher y, a continuación, reemplazar el método doExecuteBatch(...) para que parezca:

    @Override
    protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException {
        if ( batchSize == 0 ) {
            log.debug( "no batched statements to execute" );
        }
        else {
            if ( log.isDebugEnabled() ) {
                log.debug( "Executing batch size: " + batchSize );
            }

            try {
//              checkRowCounts( ps.executeBatch(), ps );
                ps.executeBatch();
            }
            catch (RuntimeException re) {
                log.error( "Exception executing batch: ", re );
                throw re;
            }
            finally {
                batchSize = 0;
            }

        }

    }

Tenga en cuenta que el nuevo método no comprobar los resultados de la ejecución de las sentencias preparadas.Tenga en cuenta que hacer este cambio podría afectar a la hibernación en cierto modo inesperado (o tal vez no).

Otros consejos

Dicen que el uso de dos factores en una tabla con particiones o el @SQLInsert anotación aquí: http://www.redhat.com/f/pdf/jbw/jmlodgenski_940_scaling_hibernate.pdf las páginas 21 a 26 (también se menciona un @SQLInsert la especificación de un método de Cadena).

Aquí está un ejemplo con un gatillo para eliminar la fila adicional en el master: https://gist.github.com/copiousfreetime/59067

Aparece si se puede usar REGLAS en lugar de disparadores para la inserción, luego de que puede devolver el número de la derecha, pero sólo con una única REGLA sin una instrucción where.

ref1

ref2

ref3

otra opción puede ser crear una vista que 'envuelve' de la tabla con particiones, a continuación, volver a la NUEVA fila para indicar el éxito de una actualización de fila, sin accidentalmente añadiendo un extra no deseado fila a la tabla maestra.

create view tablename_view as select * from tablename; -- create trivial wrapping view

CREATE OR REPLACE FUNCTION partitioned_insert_trigger() -- partitioned insert trigger
RETURNS TRIGGER AS $$
BEGIN
   IF (NEW.partition_key>= 5500000000 AND
       NEW.partition_key <  6000000000) THEN
      INSERT INTO tablename_55_59 VALUES (NEW.*);
   ELSIF (NEW.partition_key >= 5000000000 AND
          NEW.partition_key <  5500000000) THEN
      INSERT INTO tablename_50_54 VALUES (NEW.*);
   ELSIF (NEW.partition_key >= 500000000 AND
          NEW.partition_key  <  1000000000) THEN
      INSERT INTO tablename_5_9 VALUES (NEW.*);
   ELSIF (NEW.partition_key >= 0 AND
          NEW.partition_key <  500000000) THEN
      INSERT INTO tablename_0_4 VALUES (NEW.*);
   ELSE
      RAISE EXCEPTION 'partition key is out of range.  Fix the trigger function';
   END IF;
   RETURN NEW; -- RETURN NEW in this case, typically you'd return NULL from this trigger, but for views we return NEW
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER insert_view_trigger
   INSTEAD OF INSERT ON tablename_view
   FOR EACH ROW EXECUTE PROCEDURE partitioned_insert_trigger(); -- create "INSTEAD OF" trigger

ref: http://www.postgresql.org/docs/9.2/static/trigger-definition.html

Si usted fue a la vista de contenedor de ruta, una opción es también definir trivial "en lugar de" disparadores para la eliminación y actualización, así, entonces usted puede utilizar el nombre de la tabla de la vista en el lugar de su mesa normal en todas las transacciones.

Otra opción que utiliza la vista es crear una inserción de la regla, de modo que cualquier inserta en el cuadro principal, vaya a la vista de [que utiliza el disparo], ex (asumiendo que ya tiene partitioned_insert_trigger y tablename_view y insert_view_trigger creado de la lista anterior)

create RULE use_right_inserter_tablename AS
      ON INSERT TO tablename
      DO INSTEAD insert into tablename_view VALUES (NEW.*);

A continuación, hará uso de su nuevo trabajo ver contenedor de insertar.

thnx!se hizo el truco, no hay problemas poped, hasta ahora :)....una cosa te...tuve que implementar BatcherFactory la clase y lo puso int persistence.xml archivo, como este:

property name="hibernate.jdbc.factory_class" value="path.to.my.batcher.factory.implementation"

desde que la fábrica he llamado a mi dosificador aplicación con el código de arriba

ps hibernate core 3.2.6 GA

gracias una vez más

Yo enfrentan el mismo problema, mientras que la inserción de documentos a través de hibernación después de mucho buscar encontró que se está a la espera de que en las filas actualizadas debe ser devuelto así que en lugar de null cambiar a un nuevo disparo procedimiento que se va a resolver el problema como se muestra a continuación

REGRESO DE NUEVO

He encontrado otra solución para el mismo problema en esta página web:

Esto sugiere la misma solución que @rogerdpack dijo, cambiando el Devolver Null a Regreso de NUEVO, y la adición de un nuevo desencadenador que elimina la duplicación de la tupla en la maestría con la consulta:

DELETE FROM ONLY master_table;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top