sql >> Base de Datos >  >> RDS >> PostgreSQL

Excepción en JPA cuando se usa un archivo semilla para PostgreSQL

El problema no era la sintaxis, porque la sintaxis funcionaba perfectamente con flyway o directamente en la CLI de PostgreSQL. El problema fue con Hibernate, específicamente con el análisis del archivo de importación. La forma en que funciona Hibernate es que ejecuta cada expresión de los archivos individualmente, no todo el contenido como una sola expresión. Traté de poner todas las definiciones de funciones en una sola línea y funcionó, pero no era legible. Así que descubrí que hay una configuración para que Hibernate le diga que las expresiones pueden tener varias líneas, pero el $$ el delimitador aún no se reconocía cuando se usaba en varias líneas.

Entonces la solución fue definir el comando con ' delimitador y luego escapar de las comillas simples donde sea necesario con un ' adicional .

La solución es configurar spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor para usar org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor . MultipleLinesSqlCommandExtractor extrae la expresión SQL de varias líneas y se detiene cuando hay un punto y coma. Ese es el final de la expresión. Al envolver el cuerpo de la función en una cadena de comillas simples, Hibernate tratará ese envoltorio como una sola línea.

datos.sql

CREATE OR REPLACE FUNCTION insert_timeout_configuration() RETURNS bigint AS '
  DECLARE created_id bigint;

  BEGIN
    INSERT INTO timeout_configuration (id, version, timeout)
    VALUES (nextval(''my_sequence''), 0, 300)
    RETURNING id INTO created_id;
    return created_id;
  END;
' language plpgsql;

CREATE OR REPLACE FUNCTION insert_url_configuration() RETURNS bigint AS '
  DECLARE created_id bigint;

  BEGIN
    INSERT INTO url_configuration (id, version, my_url)
    VALUES (nextval(''my_sequence''), 0,''http://localhost:8080/'')
    RETURNING id INTO created_id;
    return created_id;
  END;
' language plpgsql;

DO '
      INSERT INTO global_configuration(id, version, name, timeout_configuration_id, url_configuration_id)
      VALUES (nextval(''my_sequence''), 0, ''My global config'', insert_timeout_configuration(), insert_url_configuration());

-- do some other code 
END
';
drop function insert_timeout_configuration();
drop function insert_url_configuration();

Siempre tengo que tener en cuenta escapar de las comillas simples en las expresiones, pero ahora puedo tener un archivo semilla más legible por humanos.