Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

504
Visualizações
JDBC with H2 and MySQL mode: create procedure fails

Description of code

Database connection

I try to to store Java object locally database without use external database. For this I use JDBC with H2 via Hibernate :

    /**
     * @param connection the connection to set
     */
    public static void setConnectionHibernate() {
        Properties connectionProps = new Properties();
        connectionProps.put("user", "sa");
        try {
            Class.forName("org.h2.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        url = "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MODE=MySQL;";
    }

Query

I store the PROCEDURE in String with this code :

    static final String CREATE_PROCEDURE_INITPSEUDOS = "CREATE OR REPLACE PROCEDURE init_pseudos (MaxPseudo INT) BEGIN WHILE MaxPseudo >= 0 DO"
            +
            " INSERT INTO Pseudos (indexPseudo)" +
            " VALUES (MaxPseudo);" +
            " SET MaxPseudo = MaxPseudo - 1;" +
            " END WHILE;" +
            " END init_pseudos;";

Query execution

And I execute the statement with this code :

    public static void initBaseDonneePseudos() {
        try (Connection connection = DriverManager.getConnection(url, connectionProps);
                Statement stmt = connection.createStatement()) {
            stmt.execute(RequetesSQL.CREATE_TABLE_PSEUDOS);
            stmt.execute(RequetesSQL.CREATE_PROCEDURE_INITPSEUDOS);
            stmt.execute(RequetesSQL.CREATE_FUNCTION_RECUPEREPSEUDO);
            stmt.execute(RequetesSQL.INIT_TABLE_PSEUDOS);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

Problem

Test

I execute this test to test statement :

    @Nested
    class BaseDonneeInteractionTest {

        @BeforeEach
        public void setUp() {
            BaseDonnee.setConnectionHibernate();
        }

        @Test
        void testInitBaseDonnee() {
            assertDoesNotThrow(() -> BaseDonnee.initBaseDonneePseudos());
        }

    }

Error

But I obtain this error

enter image description here

I didn't find the problem of the query, anybody have the solution to solve this ?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

The problem is that in H2 there are not explicit procedures or functions as you are trying defining.

For that purpose, H2 allows you to create used defined functions instead. Please, consider reed the appropriate documentation.

Basically, you create a user defined function by declaring an ALIAS for a bunch of Java code.

For example, in your use case, your CREATE_PROCEDURE_INITPSEUDOS could look similar to this:

CREATE ALIAS INIT_PSEUDOS AS  $$
import java.sql.Connection;
import java.sql.Statement;
import java.sql.SQLException;
@CODE
void init_pseudos(final Connection conn, final int maxPseudo) throws SQLException {
  try (Statement stmt = conn.createStatement()) {
    while (maxPseudo >= 0) do {
      stmt.execute("INSERT INTO Pseudos (indexPseudo)  VALUES (MaxPseudo);");
      maxPseudo = maxPseudo - 1;
    }
  }
}
$$;

Note the following:

  • As I said, you define a user defined function as Java code. That Java code should be enclosed between two $$ delimiters.
  • Although I included explicitly some imports, you can use any class in the java.util or java.sql packages in your code. If you want to included explicitly some imports, or if you require classes from other packages than the mentioned, the corresponding imports should be provided right after the first $$ token. In addition, you need to include @CODE the signal H2 where your imports end and your actual Java method starts.
  • If you need a reference to a Connection to the database in your code, it should be the first argument of your method.
  • Prefer to raise and not hide exceptions: it will allow your transactions to be committed or rollbacked as a whole appropriately.

You can invoke such a function as usual:

CALL INIT_PSEUDOS (5);

Please, provide the appropriate value for the maxPseudo argument.

Please, consider the provided code as just an example of use: you can improve the code in different ways, like using PreparedStatements instead of Statements for efficiency purposes, checking parameters for nullability, etcetera.

over 4 years ago · Santiago Trujillo Relatório

0

The "MySQL Compatibility Mode" doesn't make H2 100% compatible with MySQL. It just changes a few things. The documentation lists them:

  • Creating indexes in the CREATE TABLE statement is allowed using INDEX(..) or KEY(..). Example: create table test(id int primary key, name varchar(255), key idx_name(name));
  • When converting a floating point number to an integer, the fractional digits are not truncated, but the value is rounded.
  • ON DUPLICATE KEY UPDATE is supported in INSERT statements, due to this feature VALUES has special non-standard meaning is some contexts.
  • INSERT IGNORE is partially supported and may be used to skip rows with duplicate keys if ON DUPLICATE KEY UPDATE is not specified.
  • REPLACE INTO is partially supported.
  • Spaces are trimmed from the right side of CHAR values.
  • REGEXP_REPLACE() uses \ for back-references.
  • Datetime value functions return the same value within a command.
  • 0x literals are parsed as binary string literals.
  • Unrelated expressions in ORDER BY clause of DISTINCT queries are allowed.
  • Some MySQL-specific ALTER TABLE commands are partially supported.
  • TRUNCATE TABLE restarts next values of generated columns.
  • If value of an identity column was manually specified, its sequence is updated to generate values after inserted.
  • NULL value works like DEFAULT value is assignments to identity columns.
  • Referential constraints don't require an existing primary key or unique constraint on referenced columns and create a unique constraint automatically if such constraint doesn't exist.
  • LIMIT / OFFSET clauses are supported.
  • AUTO_INCREMENT clause can be used.
  • YEAR data type is treated like SMALLINT data type.
  • GROUP BY clause can contain 1-based positions of expressions from the SELECT list.
  • Unsafe comparison operators between numeric and boolean values are allowed.

That's all. There is nothing about procedures. As @jccampanero pointed out in the other answer, you must use the syntax specific to H2 if you want to create stored procedures.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda