Question

Version TL; DR: Je veux pouvoir utiliser le plugin Maven Mojo SQL pour créer / supprimer n'importe quelle table donnée dans mon schéma DB (ou charger des données pour ces tables) à volonté via la ligne de commande mvn. Comment?


Je suis un développeur Java de longue date, mais pour la plupart, j'ai vécu dans un monde basé sur des codes génériques. J'aime la puissance et l'explicitation du ant, et le contrôle qu'il me donne sur tout. Cependant, dans mon nouveau travail, il y a une poussée pour utiliser ant. J'ai donc décidé de l'apprendre en utilisant un projet sur lequel je travaille chez moi.

Une des choses que j'ai configurées sur un projet personnel différent est la possibilité de configurer et de détruire complètement ma base de données Postgres à partir de maven sur la ligne de commande. Je peux découper en dés toutes les données de test de table, de séquence et d'intégration que je veux, individuellement ou de concert. Bien sûr, cela signifie que j'ai environ un gajillion de cibles ant, mais cela fonctionne très bien. J'aime ça; cela m'a très bien servi au fil des ans.

En recherchant comment accomplir cela dans Maven ce week-end, j'ai trouvé le Plugin Mojo SQL Maven . Après avoir consulté la page d'utilisation (et j'utilise ce terme de manière vague, car il ne s'agit en réalité que d'un seul semi-exemple sans explications) et la page d'exemples , j'ai pu apporter des modifications à mon fichier ant. J'ai corrigé des fautes de frappe évidentes dans l'exemple (postgressql) et référencé la page JDBC PostgreSQL pour m'assurer que la chaîne de connexion JDBC est correcte. Je vais coller tout le pom.xml (modifié pour protéger les coupables) ci-dessous:

<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>

Maintenant, comme je n'ai pas créé la base de données, elle n'apparaît pas dans un pom.xml sur la ligne de commande 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)

Ainsi, lorsque j'exécute \l, je m'attends à ce que ma base de données soit créée ... Ou du moins ne pas échouer sur la tâche mvn sql:execute puisque cela est configuré pour continuer en cas d'erreur. Mais bien sûr:

[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 page d'erreur mentionnée sur la dernière ligne n'est pas utile; il me dit simplement qu'un plugin a causé l'erreur, pas Maven lui-même.

Alors, exécutons-le avec le commutateur drop-db-before-test-if-any. Je vais juste poster la partie intéressante de l'erreur:

[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

Mais, mais, mais ... -X!

Alors, aux questions:

  1. Qu'est-ce que je fais de mal? Est-ce mes attentes ou mon code?
  2. Vous remarquerez que j'ai un fichier <onError>continue</onError>. Je sais d'après les exemples que je peux y avoir plusieurs fichiers, tels que create-person.sql. Mais dans create-address.sql, j'ai la possibilité de créer la table ant séparément de la table address, tant que j'effectue les tâches de fourmi en gardant à l'esprit l'ordre d'intégrité référentielle. Est-ce que quelque chose comme ça est possible avec person? Si oui, comment?

Désolé pour la verbosité, et merci d'avance pour toute aide.

Était-ce utile?

La solution

Échec de l'exécution de l'objectif org.codehaus.mojo: sql-maven-plugin: 1.5: exécution (default-cli)

default-cli est le executionId spécial lorsque le plugin est appelé à partir de la ligne de commande.Voir ceci .

Vous avez lié toute l'exécution du plugin sql aux phases du cycle de vie maven, mais vous essayez d'appeler le plugin directement.

mvn test devrait fonctionner.

Voici une discussion SO connexe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top