PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Exceção no JPA ao usar arquivo semente para PostgreSQL


O problema não era a sintaxe, pois a sintaxe funcionava perfeitamente com flyway ou diretamente na CLI do PostgreSQL. O problema era com o Hibernate, especificamente com a análise do arquivo de importação. A maneira como o Hibernate funciona é que ele executa cada expressão dos arquivos individualmente, não todo o conteúdo como uma única expressão. Tentei colocar todas as definições de função em uma linha e funcionou, mas não ficou legível. Então eu descobri que existe uma configuração para o Hibernate para dizer que as expressões podem ser multi-linhas, mas o $$ delimitador ainda não foi reconhecido quando usado em várias linhas.

Então a solução foi definir o comando com ' delimitador e, em seguida, escape das aspas simples quando necessário com um ' adicional .

A solução é definir o spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor para usar org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor . MultipleLinesSqlCommandExtractor extrai a expressão SQL de várias linhas e para quando um ponto e vírgula está presente. Esse é o fim da expressão. Ao envolver o corpo da função em uma string de aspas simples, o Hibernate tratará essa quebra como uma única linha.

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

Eu tenho que sempre ter em mente escapar das aspas simples nas expressões, mas agora eu posso ter um arquivo de semente mais legível para humanos.