PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Eccezione in JPA quando si utilizza il file seme per PostgreSQL

Il problema non era la sintassi, perché la sintassi funzionava perfettamente con flyway o direttamente nella CLI di PostgreSQL. Il problema era con Hibernate, in particolare con l'analisi del file di importazione. Il modo in cui Hibernate funziona è che esegue ogni espressione dai file individualmente, non l'intero contenuto come una singola espressione. Ho provato a mettere tutte le definizioni delle funzioni in una riga e ha funzionato, ma non era leggibile. Quindi ho scoperto che esiste una configurazione per Hibernate per dirgli che le espressioni possono essere a più righe, ma il $$ delimitatore non era ancora riconosciuto quando utilizzato in multilinea.

Quindi la soluzione era definire il comando con ' delimitatore e quindi sfuggire alle virgolette singole dove necessario con un ulteriore ' .

La soluzione è impostare spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor per usare org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor . MultipleLinesSqlCommandExtractor estrae l'espressione SQL da più righe e si interrompe quando è presente un punto e virgola. Questa è la fine dell'espressione. Avvolgendo il corpo della funzione in una stringa tra virgolette singole, Hibernate tratterà tale avvolgimento come una singola riga.

data.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();

Devo sempre tenere a mente di evitare le virgolette singole nelle espressioni, ma ora posso avere un file seme più leggibile dall'uomo.