PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Exception dans JPA lors de l'utilisation du fichier de départ pour PostgreSQL

Le problème n'était pas la syntaxe, car la syntaxe fonctionnait parfaitement avec flyway ou directement dans PostgreSQL CLI. Le problème était avec Hibernate, en particulier avec l'analyse du fichier d'importation. La façon dont Hibernate fonctionne est qu'il exécute chaque expression des fichiers individuellement, et non l'ensemble du contenu en une seule expression. J'ai essayé de mettre toutes les définitions de fonctions sur une seule ligne et cela a fonctionné, mais ce n'était pas lisible. J'ai donc trouvé qu'il existe une configuration pour Hibernate pour lui dire que les expressions peuvent être multi-lignes, mais le $$ le délimiteur n'était toujours pas reconnu lorsqu'il était utilisé en multiligne.

La solution était donc de définir la commande avec ' délimiteur, puis échappez les guillemets simples si nécessaire avec un ' supplémentaire .

La solution consiste à définir le spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor utiliser org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor . MultipleLinesSqlCommandExtractor extrait l'expression SQL de plusieurs lignes et s'arrête lorsqu'un point-virgule est présent. C'est la fin de l'expression. En enveloppant le corps de la fonction dans une chaîne entre guillemets simples, Hibernate traitera cet emballage comme une seule ligne.

données.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();

Je dois toujours garder à l'esprit d'échapper aux guillemets simples dans les expressions, mais maintenant je peux avoir un fichier de départ plus lisible par l'homme.