2016-05-08 30 views
5

Ich habe Spring-Anwendung erstellt. Pom Xml ist beigefügt.Spring Boot: Hibernate und Flyway Boot-Reihenfolge

Es hat eine Konfiguration wie diese (unten) und einige db/migration/V1__init.sql für Flyway db Migrationstool.

Es hat hsqldb In-Memory-Datenbank und es wird erstellt, nachdem die Anwendung gestartet wurde. Es ist sauber nach der Erstellung.

Ich möchte Hibernate ein Schema basierend auf Entity-Klassen erstellen und dann füllt Flyway die Tabellen. Jetzt startet Flyway V1__init.sql, bevor Tabellen erstellt werden, und löst eine Ausnahme aus. Wie kann ich diese Reihenfolge ändern oder welche Lösung kann ich machen?

spring.datasource.testWhileIdle = true 
spring.datasource.validationQuery = SELECT 1 
spring.jpa.show-sql = true 
spring.jpa.hibernate.ddl-auto = create-drop 
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy 
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.HSQLDialect 

pom.xml:

<parent> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>1.3.3.RELEASE</version> 
    <relativePath/> 
</parent> 

<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <java.version>1.8</java.version> 
</properties> 

<dependencies> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-web</artifactId> 
     <version>1.3.2.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.hsqldb</groupId> 
     <artifactId>hsqldb</artifactId> 
     <scope>runtime</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-core</artifactId> 
     <version>4.3.11.Final</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-orm</artifactId> 
     <version>4.2.5.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.thymeleaf</groupId> 
     <artifactId>thymeleaf-spring4</artifactId> 
     <version>2.1.4.RELEASE</version> 
    </dependency> 

    <!-- For using 'LEGACYHTML5' mode in Thymeleaf --> 
    <dependency> 
     <groupId>net.sourceforge.nekohtml</groupId> 
     <artifactId>nekohtml</artifactId> 
     <version>1.9.21</version> 
    </dependency> 
    <dependency> 
     <groupId>xml-apis</groupId> 
     <artifactId>xml-apis</artifactId> 
     <version>1.4.01</version> 
    </dependency> 

    <dependency> 
     <groupId>org.flywaydb</groupId> 
     <artifactId>flyway-core</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-data-jpa</artifactId> 
     <version>1.3.3.RELEASE</version> 
    </dependency> 
</dependencies> 

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-maven-plugin</artifactId> 
     </plugin> 
    </plugins> 
</build> 
+2

Unrelated auf Ihre Frage, aber Sie sollten viele der Versionen von Ihrem pom entfernen und lassen Stiefel sie für Sie konfigurieren. Und Sie sollten sicherlich keine Versionen von Spring Boot selbst mischen (Sie haben 1.3.2.RELEASE und 1.3.3.RELEASE). –

Antwort

1

Ich habe meine Aufgabe gelöst. Ich habe Flyway entfernt und einfach data.sql hinzugefügt

8

Automatische Boot-Konfiguration von Flyway stellt sicher, dass Datenbankmigrationen ausgeführt wurden, bevor Hibernate initialisiert wird. Mit anderen Worten, Sie können sich nicht auf die automatische Flyway-Konfiguration verlassen und Flyway zum Füllen von Tabellen verwenden, die von Hinernate erstellt wurden.

Eine Lösung besteht darin, Flyway vollständig zu integrieren und es sowohl zum Erstellen der Tabellen als auch zum Auffüllen der Tabellen zu verwenden. Sie können dann die Erstellung der Hibernate-Tabelle ausschalten (spring.jpa.hibernate.ddl-auto=none). Dieser Ansatz ist robuster, da er die Entwicklung Ihrer Datenbank vereinfacht. Das würde ich dir empfehlen.

Eine andere Lösung besteht darin, die automatische Konfiguration von Flyway (flyway.enabled=false) zu deaktivieren und sie selbst zu konfigurieren. Sie können Flyway so konfigurieren, dass er von Hibernate abhängig ist, sodass Hibernate die Tabellen erstellt hat, bevor Flyway versucht, sie zu füllen.

+1

Haben Sie einen Beispielcode für Ihren zweiten Vorschlag? –

+0

Wir wünschen, dass das stimmt.Eigentlich läuft Hibernate derzeit zuerst und das ist ein offenes Problem. – sofend

+1

@sofend Ich glaube, dass Sie sich irren und die Frage schlägt auch so vor. Wir haben auch Tests in Boot, die sicherstellen, dass Flyway-Migrationen vor Hibernate ausgeführt werden. Was lässt Sie denken, dass Hibernate zuerst läuft? –

6

Ich hatte das gleiche Problem.

Ich wollte, dass mein Schema wegen seiner Datenbankunabhängigkeit von Hibernate erstellt wird. Ich habe bereits die Mühe gemacht, in meinen jpa-Kursen ein schönes Schema für meine Bewerbung zu finden, ich wiederhole mich nicht gerne.

Aber ich möchte einige Dateninitialisierung in einer versionierten Art und Weise durchgeführt werden, die Flugweg ist gut.

Der Spring Boot läuft vor dem Winterschlaf. Um es zu ändern, habe ich den Spring-Boot-Initialisierer übergangen, um nichts zu tun. Dann habe ich einen zweiten Initialisierer erstellt, der nach dem Ruhezustand ausgeführt wird. Alles, was Sie tun müssen, ist diese Konfiguration Klasse hinzufügen:

import org.flywaydb.core.Flyway; 
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.DependsOn; 

@Configuration 
public class MigrationConfiguration { 


    /** 
    * Override default flyway initializer to do nothing 
    */ 
    @Bean 
    FlywayMigrationInitializer flywayInitializer(Flyway flyway) { 
     return new FlywayMigrationInitializer(flyway, (f) ->{}); 
    } 


    /** 
    * Create a second flyway initializer to run after jpa has created the schema 
    */ 
    @Bean 
    @DependsOn("entityManagerFactory") 
    FlywayMigrationInitializer delayedFlywayInitializer(Flyway flyway) { 
     return new FlywayMigrationInitializer(flyway, null); 
    } 


} 

Dieser Code benötigt Java 8, wenn Sie Java 7 oder früher haben, ersetzen (f)->{} mit einer inneren Klasse, die FlywayMigrationStrategy

Natürlich führt Sie tun können Dies in XML genauso einfach.

Achten Sie darauf, dies zu Ihrem application.properties hinzuzufügen:

flyway.baselineOnMigrate = true 
+1

Das funktioniert super. Anstelle von @DependsOn bevorzuge ich es, nur einen Parameter zu deklarieren (dann ist es stark typisiert), aber dieses Überschreiben der Flugweg-Initialisierung ist äußerst nützlich. Vielen Dank! –

+0

Schön, aber ich habe es ausprobiert und es kann meinen entitymanagerfactory nicht nach seinem Namen lokalisieren. – djangofan

+0

Haben Sie Ihrer pom.xml Springdaten jpa hinzugefügt? Überprüfe, was die Autokonfiguration macht. Oder wie Paul Hilliar sagte, spritze es nach Typ – user3707816

Verwandte Themen