Pregunta

Tl; versión dr: quiero poder usar el complemento Maven Mojo SQL para crear/soltar cualquier tabla dada en mi esquema de DB (o cargar datos para esas tablas) a voluntad a través de la voluntad mvn línea de comando. ¿Cómo?


Soy un desarrollador de Java desde hace mucho tiempo, pero en su mayor parte he estado viviendo en un ant-Lau del mundo basado. Me gusta el poder y la explicidad de ant, y el control de que me da sobre todo. Sin embargo, en mi nuevo trabajo, hay un impulso para usar maven. Así que decidí aprenderlo usando un proyecto en el que estoy trabajando en casa.

Una de las cosas que he establecido en un proyecto personal diferente es la capacidad de configurar y derribar por completo mi base de datos de Postgres de ant en la línea de comando. Puedo cortar y decas en cualquier tabla, secuencia y datos de prueba de integración que complace, individualmente o en concierto. Claro, significa que tengo alrededor de un Gajillion ant Objetivos, pero funciona muy bien. Me gusta esto; Me ha servido bastante bien a lo largo de los años.

Al investigar cómo lograr esto en Maven durante el fin de semana, encontré el MOJO SQL Maven Plugin. Después de mirar el página de uso (Y uso ese término libremente, ya que en realidad es solo un semi-ejemplos sin explicaciones) y el página de ejemplo, Pude encontrar algunos cambios en mi pom.xml expediente. Arreglé algunos errores tipográficos obvios en el ejemplo (PostgressQL), y referí al Página de PostgreSQL JDBC Para asegurarme de tener la cadena de conexión JDBC correcta. Pegaré todo el pom.xml (modificado para proteger al culpable) a continuación:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany.myapp</groupId>
    <artifactId>myapp</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>myapp</name>
    <url>http://maven.apache.org</url>

    <repositories>
        <repository>
            <id>JBoss</id>
            <url>https://repository.jboss.org/nexus/content/groups/public/</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.0.0.CR7</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>sql-maven-plugin</artifactId>
                <version>1.5</version>

                <dependencies>
                    <dependency>
                        <groupId>postgresql</groupId>
                        <artifactId>postgresql</artifactId>
                        <version>8.3-606.jdbc4</version>
                    </dependency>
                </dependencies>

                <configuration>
                    <driver>org.postgresql.Driver</driver>
                    <url>jdbc:postgresql://localhost:5432/myapp</url>
                    <settingsKey>myapp</settingsKey>
                    <!--all executions are ignored if -Dmaven.test.skip=true-->
                    <skip>${maven.test.skip}</skip>
                </configuration>

                <executions>
                    <execution>
                        <id>drop-db-before-test-if-any</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <!-- need another database to drop the targeted one -->
                            <url>jdbc:postgresql://localhost:5432/template1</url>
                            <autocommit>true</autocommit>
                            <sqlCommand>drop database myapp</sqlCommand>
                            <!-- ignore error when database is not avaiable -->
                            <onError>continue</onError>
                        </configuration>
                    </execution>

                    <execution>
                        <id>create-db</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <url>jdbc:postgresql://localhost:5432/template1</url>
                            <!-- no transaction -->
                            <autocommit>true</autocommit>
                            <sqlCommand>create database myapp</sqlCommand>
                        </configuration>
                    </execution>

                    <execution>
                        <id>create-schema</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <autocommit>true</autocommit>
                            <srcFiles>
                                <srcFile>src/main/sql/create_person.sql</srcFile>
                            </srcFiles>
                        </configuration>
                    </execution>

                    <execution>
                        <id>create-data</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <orderFile>ascending</orderFile>
                            <fileset>
                                <basedir>${basedir}</basedir>
                                <includes>
                                    <include>src/test/sql/person_data.sql</include>
                                </includes>
                            </fileset>
                        </configuration>
                    </execution>

                    <!-- drop db after test -->
                    <execution>
                        <id>drop-db-after-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>execute</goal>
                        </goals>
                        <configuration>
                            <url>jdbc:postgresql://localhost:5432/template1</url>
                            <autocommit>true</autocommit>
                            <sqlCommand>drop database myapp</sqlCommand>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Ahora, dado que no he creado la base de datos, no aparece en un \l En la línea de comandos de PG:

[mike@mike myapp]$ psql template1
Welcome to psql 8.3.5, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

template1=# \l
        List of databases
   Name    |  Owner   | Encoding 
-----------+----------+----------
 postgres  | postgres | UTF8
 template0 | postgres | UTF8
 template1 | postgres | UTF8
(3 rows)

Así, cuando corro mvn sql:execute, Espero que se cree mi base de datos ... o al menos no fallar en el drop-db-before-test-if-any Tarea ya que eso está configurado para continuar con el error. Pero por supuesto:

[mike@mike myapp]$ mvn sql:execute
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building myapp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- sql-maven-plugin:1.5:execute (default-cli) @ myapp ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.667s
[INFO] Finished at: Mon Dec 05 20:22:17 CST 2011
[INFO] Final Memory: 3M/81M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute (default-cli) on project myapp: FATAL: database "myapp" does not exist -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

La página de error mencionada en la última línea no es útil; Simplemente me dice que un complemento causó el error, no en el propio Maven.

Así que vamos a ejecutarlo con el -X cambiar. Publicaré la parte interesante del error:

[ERROR] Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute (default-cli) on project myapp: FATAL: database "myapp" does not exist -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute (default-cli) on project myapp: FATAL: database "myapp" does not exist
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoExecutionException: FATAL: database "myapp" does not exist
    at org.codehaus.mojo.sql.SqlExecMojo.execute(SqlExecMojo.java:618)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
Caused by: org.postgresql.util.PSQLException: FATAL: database "myapp" does not exist
    at org.postgresql.core.v3.ConnectionFactoryImpl.readStartupMessages(ConnectionFactoryImpl.java:444)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:99)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
    at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:124)
    at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:30)
    at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:29)
    at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24)
    at org.postgresql.Driver.makeConnection(Driver.java:386)
    at org.postgresql.Driver.connect(Driver.java:260)
    at org.codehaus.mojo.sql.SqlExecMojo.getConnection(SqlExecMojo.java:899)
    at org.codehaus.mojo.sql.SqlExecMojo.execute(SqlExecMojo.java:612)
    ... 21 more

Pero pero pero...<onError>continue</onError>!

Entonces, a las preguntas:

  1. ¿Qué estoy haciendo mal? ¿Son mis expectativas o mi código?
  2. Notarás que tengo un create-person.sql expediente. Sé por los ejemplos que puedo tener múltiples archivos allí, como create-address.sql. Pero en ant, Tengo la capacidad de crear el address mesa por separado del person Tabla, siempre y cuando realice las tareas de hormigas teniendo en cuenta el orden de la integridad referencial. Es algo así posible con maven? ¿Si es así, cómo?

Perdón por la verbosidad, y gracias de antemano por cualquier ayuda.

¿Fue útil?

Solución

No se pudo ejecutar el objetivo org.codehaus.mojo: SQL-Maven-Plugin: 1.5: Ejecutar (CLI predeterminado)

default-cli es el especial executionId Cuando el complemento se invoca desde la línea de comandos. Ver este.

Ha limitado toda la ejecución del complemento SQL para maven las fases del ciclo de vida, pero está tratando de invocar el complemento directamente.

mvn test Deberia trabajar.

Aquí es una discusión relacionada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top