Spring Boot kann nicht zum automatischen Erstellen eines Datenbankschemas abgerufen werden

76

Ich kann Spring Boot nicht dazu bringen, mein Datenbankschema beim Starten automatisch zu laden.

Hier ist meine application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=test
spring.datasource.password=
spring.datasource.driverClassName = com.mysql.jdbc.Driver

spring.jpa.database = MYSQL

spring.jpa.show-sql = true

spring.jpa.hibernate.ddl-auto = create
spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy

Hier ist meine Application.java:

@EnableAutoConfiguration
@ComponentScan
public class Application {
    public static void main(final String[] args){
        SpringApplication.run(Application.class, args);
    }
}

Hier ist eine Beispielentität:

@Entity
@Table(name = "survey")
public class Survey implements Serializable {

    private Long _id;

    private String _name;

    private List<Question> _questions;

    /**
     * @return survey's id.
     */
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "survey_id", unique = true, nullable = false)
    public Long getId() {
        return _id;
    }

    /**
     * @return the survey name.
     */
    @Column(name = "name")
    public String getName() {
        return _name;
    }


    /**
     * @return a list of survey questions.
     */
    @OneToMany(mappedBy = "survey")
    @OrderBy("id")
    public List<Question> getQuestions() {
        return _questions;
    }

    /**
     * @param id the id to set to.
     */
    public void setId(Long id) {
        _id = id;
    }

    /**
     * @param name the name for the question.
     */
    public void setName(final String name) {
        _name = name;
    }

    /**
     * @param questions list of questions to set.
     */
    public void setQuestions(List<Question> questions) {
        _questions = questions;
    }
}

Irgendwelche Ideen, was ich falsch mache?

Napentathol
quelle
2
Welche Ausnahme / Fehler wirft es?
CocoNess
Keine Ausnahmen, es wird gestartet und läuft dann einwandfrei, bis es versucht, mit der Datenbank zu interagieren. Dann wird eine Ausnahme ausgelöst, dass keine Tabellen vorhanden sind. Keine relevanten Warnungen im Protokoll.
Napentathol

Antworten:

91

Es gibt mehrere mögliche Ursachen:

  1. Ihre Entitätsklassen befinden sich in derselben oder in einer Unterpaket-Relativklasse, mit der Sie @EnableAutoConfiguration.Ihre Klasse haben. Wenn nicht, sieht Ihre Spring-App sie nicht und erstellt daher nichts in db
  2. Überprüfen Sie Ihre Konfiguration. Es scheint, dass Sie einige Optionen für den Ruhezustand verwenden. Versuchen Sie, diese durch Folgendes zu ersetzen:

    spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
    spring.jpa.hibernate.ddl-auto=update
    spring.datasource.driverClassName=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/test
    spring.datasource.username=test
    spring.datasource.password=
    
  3. Sie application.propertiesmüssen sich im src/main/resourcesOrdner befinden.

Wenn Sie den Dialekt nicht korrekt angegeben haben, wird möglicherweise versucht, standardmäßig zusammen mit der Boot-In-Memory-Datenbank gebündelt zu werden, und (wie bei mir) konnte ich feststellen, dass versucht wird, eine Verbindung zur lokalen HSQLInstanz (siehe Konsolenausgabe) herzustellen, und die Aktualisierung der fehlgeschlagen ist Schema.

borys86
quelle
19
Ändern des Dialekts, um org.hibernate.dialect.MySQL5InnoDBDialectden Trick zu tun. Danke für die Hilfe!
Napentathol
2
Die Nummer 1 funktioniert für mich. Was kann ich tun, wenn ich mein Modell nicht mit meiner Hauptklasse im selben Projekt haben möchte? Ich habe mit dem Modellpaket Komponentenscan hinzugefügt, aber ich habe mir nicht geholfen.
Emoleumassi
@ O.Badr, gültiger Kommentar. Ich habe höchstwahrscheinlich Zeilen aus einer Reihe von Konfigurationsdateien eingefügt, die ich gleichzeitig hatte. Dialekt und Treiber sollten mit der Zieldatenbank übereinstimmen.
Borys86
2
@ borys86, also sollten wir in Ihrer Lösung org.hibernate.dialect.MySQL5InnoDBDialectstattdessen verwenden, da die Frage über MySQL war!
O.Badr
1
# 2 hat für mich funktioniert, aber spring.datasource.driverClassName = com.mysql.jdbc.Driver wird nicht benötigt und gibt eine Warnung aus: Laden der Klasse com.mysql.jdbc.Driver'. This is deprecated. The new driver class is com.mysql.cj.jdbc.Driver '. Der Treiber wird automatisch über das SPI registriert und das manuelle Laden der Treiberklasse ist in der Regel nicht erforderlich.
BaDr Amer
56

Haben Sie versucht, es auszuführen mit:

spring.jpa.generate-ddl=true

und dann

spring.jpa.hibernate.ddl-auto = create

Standardmäßig wird die DDL-Ausführung (oder Validierung) verschoben, bis der ApplicationContext gestartet wurde. Es gibt auch ein spring.jpa.generate-ddl-Flag, das jedoch nicht verwendet wird, wenn die automatische Konfiguration des Ruhezustands aktiv ist, da die Einstellungen für ddl-auto genauer sind.

siehe Spring-Boot-Features

Liorsolomon
quelle
Ja, es mit diesen Eigenschaften auszuführen hat auch nicht funktioniert. Es ist seltsam, dass nicht einmal der Eigenschaftswert in der Jconsole angezeigt wird:spring.jpa.CONFIGURATION_PROPERTIES={prefix=spring.jpa, properties={databasePlatform=null, database=MYSQL, generateDdl=false, showSql=false}}
Napentathol
1
Könnte es sein, dass der Benutzer, der die Abfragen ausführt, keine Berechtigung zum Erstellen der Tabellen hat? Erhalten Sie Fehler?
Liorsolomon
Der Benutzer ist derselbe Benutzer, der das Schema erstellt hat: /. Keine Fehler, bis ich den Rest Controller drücke, der die Datenbank trifft.
Napentathol
Dieser hat für mich funktioniert <property name = "hibernate.hbm2ddl.auto"> create </ property>
abbas
18
@SpringBootApplication
@EnableConfigurationProperties
@EntityScan(basePackages = {"com.project.ppaa.model"})  // scan JPA entities
public class Application {

  private static ConfigurableApplicationContext applicationContext;

  public static void main(String[] args) {
    Application.applicationContext = SpringApplication.run(Application.class, args);
  }
}

Es sollte automatisch funktionieren, aber wenn dies nicht der Fall ist, können Sie das Basispaket eingeben

@EntityScan(basePackages = {"com.project.ppaa.model"})  // scan JPA entities manually
Ar maj
quelle
Es funktioniert für mich, Spring Boot Version: 1.5.9.RELEASE. Ich finde jedoch, dass die Hauptursache darin besteht, dass ich ApplicationConfig in das übergeordnete Paket meines Entitätspakets einfügen sollte. Es könnte also automatisch die Entitäten in der Hierarchie scannen.
MageXellos
das hat bei mir funktioniert. Danke vielmals. Ich habe Stunden gebraucht, um dieses Problem zu beheben. Die Sache war, es wurde kein Fehler geworfen oder auch nur eine Info. Gar nichts, ich habe blind versucht, jedes Keyword für dieses Problem zu durchsuchen. Ich weiß jedoch immer noch nicht, warum meine Entitäten nicht automatisch gescannt werden. : /
iamjoshua
Dies half mir, als mein Dao und Repository, Entitätsklassen in verschiedenen Maven-Modulen waren
Anshulkatta
11

Die Verwendung der folgenden beiden Einstellungen funktioniert.

spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
Taf
quelle
gehört das in die Datei application.properties?
Alexander Mills
Ja, Sie fügen diese in application.properties hinzu. Alternativ können Sie die Eigenschaften in Ihrer SpringBootApplication-Hauptklasse konfigurieren.
Taf
7

Wenn sich Ihre Entitätsklasse nicht im selben Paket wie Ihre Hauptklasse befindet, können Sie @EntityScanAnmerkungen in der Hauptklasse verwenden und die Entität angeben, die Sie speichern oder auch packen möchten. Wie Ihr Modellpaket.

Über:

spring.jpa.hibernate.ddl-auto = create

Sie können die Option verwenden update. Es werden keine Daten gelöscht und Tabellen auf die gleiche Weise erstellt.

erickbhrener
quelle
5

Dies habe ich getan, nachdem ich alle obigen Antworten gelesen hatte.

  1. Fügen Sie spring.jpa.hibernate.ddl-auto=updatemit anderen einfachen Eigenschaften application.properties hinzu
  2. Lauf
  3. In der Konsole sehen Sie den Fehler. An einer Stelle im Fehler finden Sie den von dieser Software generierten SQL-Code zum Erstellen Ihrer Entitätstabelle.
  4. Kopieren Sie diesen SQL-Code und fügen Sie ihn separat in Ihr DBMS ein, um die Tabelle zu erstellen.
  5. Führen Sie danach die App erneut aus.
Udith Indrakantha
quelle
4

Sie fügen einfach createDatabaseIfNotExist=truewie diese

spring.datasource.url=jdbc:mysql://localhost:3306/test?createDatabaseIfNotExist=true&amp;amp;useUnicode=true&amp;amp;characterEncoding=utf-8&amp;amp;autoReconnect=true

in Ihre application.properties-Datei

Abderrahmane BECHIKH
quelle
4

Die Antwort von Abderrahmane ist korrekt: ?createDatabaseIfNotExist=trueFügen Sie die Eigenschaft url hinzu. Es scheint, dass ddl-autodas nichts bringt.

Camilo
quelle
1
Bei der Frage geht es nicht um das Erstellen einer Datenbank, sondern darum, dass Spring JPA keine Tabellen in der Datenbank erstellt. Die Datenbank wurde möglicherweise erstellt, aber die Tabellen wurden nicht gesetzt
ken4ward
4
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update

MySQL5Dialect ist ein Trick, zuvor habe ich 'MySQLDialect' verwendet.

asifaftab87
quelle
Das Hinzufügen von `` `spring.jpa.generate-ddl = true` `` hat den Trick gemacht. Nur mit `` `spring.jpa.hibernate.ddl-auto = update` ``. Standardnähte sind falsch.
Christoph Raab
4

Ich habe meinen Fall mit dieser Lösung gelöst. Haben Sie gerade einen neuen Parameter createDatabaseIfNotExist = true in eine spring.datasource.url- Eigenschaft in einer application.properties- Datei eingefügt , wie folgt :

spring.datasource.url=jdbc:mysql://localhost:3306/minhasenha?autoReconnect=true&useSSL=false&createDatabaseIfNotExist=true

Ich habe die Datei src / main / resources / Schema.sql mit DDL, um das Datenbankschema zu erstellen. Und ich habe flyaway verwendet , um die Tabellen zu erstellen und zu pflegen.

Ich habe diese Lösung hier gegründet: ursprüngliche Antwort

Jesus
quelle
3

In meinem Fall wurden die Tabellen nicht automatisch erstellt, obwohl ich JPArepository verwendet habe. Nach dem Hinzufügen der folgenden Eigenschaft in meiner Datei springboot app application.properties werden die Tabellen jetzt automatisch erstellt. spring.jpa.hibernate.ddl-auto = update

Jayant Nayak
quelle
3

Sie müssen Konfigurationen bereitstellen, die Ihre Spring Boot-Version und die Version der Bibliotheken berücksichtigen, die darauf basierend heruntergeladen werden.

Mein Setup: Spring Boot 1.5.x (in meinem Fall 1.5.10) lädt Hibernate v5.x herunter

Verwenden Sie unten nur, wenn Ihr Spring Boot-Setup Hibernate v4 heruntergeladen hat.

spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy

Hibernate 5 wird oben nicht unterstützt.

Wenn Ihr Spring Boot Setup Hibernate v5.x heruntergeladen hat, bevorzugen Sie die folgende Definition:

spring.jpa.hibernate.naming.physical-Strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

WICHTIG: In Ihrer Spring Boot-Anwendungsentwicklung sollten Sie lieber die Anmerkung verwenden: @SpringBootApplicationdie mit folgenden Anmerkungen versehen wurde:@SpringBootConfiguration and @EnableAutoConfiguration

JETZT Wenn sich Ihre Entitätsklassen in einem anderen Paket befinden als das Paket, in dem sich Ihre Hauptklasse befindet, scannt Spring Boot diese Pakete nicht.

Daher müssen Sie Annotation explizit definieren: @EntityScan(basePackages = { "com.springboot.entities" })
Diese Annotation scannt JPA-basierte annotierte Entitätsklassen (und andere wie MongoDB, Cassandra usw.)

HINWEIS: "com.springboot.entities" ist der benutzerdefinierte Paketname.

Im Folgenden habe ich die Eigenschaften von Hibernate und JPA auf application.properties definiert, um Tabellen zu erstellen:

spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.url = jdbc: mysql: // localhost: 3333 / development? useSSL = true spring.datasource.username = admin
spring.datasource.password =

spring.jpa.open-in-view = false
spring.jpa.hibernate.ddl-auto = create
spring.jpa.generate-ddl = true
spring.jpa.hibernate.use-new-id-generator-mappings = true
spring. jpa.hibernate.naming.physical-Strategie = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.naming.strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.show-sql = true
spring.jpa .properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.format_sql = true

Ich kann Tabellen mit meiner oben genannten Konfiguration erstellen.

Verweisen Sie darauf und ändern Sie gegebenenfalls Ihren Code.

Philip Dilip
quelle
2

Ich habe auch das gleiche Problem. Es stellte sich heraus, dass für die Hauptanwendungsklasse die Annotation @PropertySource festgelegt wurde, um eine andere Basiseigenschaftendatei zu lesen, sodass die normale "application.properties" nicht mehr verwendet wird.

user3206144
quelle
2

Leider hat für mich keine der oben angegebenen Antworten funktioniert, da ich später herausfand, dass das Problem aus meiner pomDatei stammt. Ich habe das Spring Boot Starter Projekt verwendet und eine andere Art von Spring JPA hinzugefügt, die nicht funktioniert hat. Anfangs hatte ich das,

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
    </dependency> 

Ich habe es dadurch ersetzt:

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
   </dependency> 

Beachten Sie die Spring-Boot-Starter-Daten-jpa . Hoffentlich kann das jemandem helfen. Überprüfen Sie Ihre POM-Datei und stellen Sie sicher, dass Ihre Abhängigkeiten übereinstimmen.

leeCoder
quelle
1

Ich hatte vorher das gleiche Problem. Mein Problem war die Entitätsbeziehung, die ich mithilfe einer "Liste" herstellen wollte. Ich wusste, dass dies die Ursache war, da das Programm ohne die Listenvariable einwandfrei lief. In Ihrem Fall denke ich, dass das Problem ist:

private List<Question> _questions;

Ich gehe davon aus, dass Sie bereits eine Klasse namens Frage haben. Versuchen Sie also:

@OneToMany
private Question _questions;

Aber die Sache ist, in Ihrer Methode werden Sie damit umgehen, damit es eine Liste zurückgibt. Ich habe Spring Data JPA mit CrudRepository verwendet. Wenn Sie sich also für die Verwendung entscheiden, sieht Ihre möglicherweise folgendermaßen aus:

public List<Question> findById( Long _id );

Es gibt weitere Änderungen, die Sie vornehmen müssen, aber diese sind ziemlich einfach und unkompliziert. In diesem Java Brains-Video können Sie besser verstehen, was noch geändert werden muss.

lamarre
quelle
1

Fügen Sie einfach den Parameter createDatabaseIfNotExist = true in die URL der Spring-Datenquelle ein

Beispiel: spring.datasource.url = jdbc: mysql: // localhost: 3306 / test? CreateDatabaseIfNotExist = true

Nitin Pawar
quelle
1

Ich bin auf ein ähnliches Problem gestoßen. Ich verwende Spring Boot 2.x und habe es versäumt, die Postgres-Abhängigkeit beim Spring-Initialisierer hinzuzufügen. Ich habe die Abhängigkeit manuell hinzugefügt

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>

und hier ist, was ich bekam - INFO org.hibernate.dialect.Dialect - HHH000400: Verwenden von dialect: org.hibernate.dialect.PostgreSQLDialect anstelle von

**INFO  org.hibernate.dialect.Dialect - HHH000400: Using 
dialect:org.hibernate.dialect.PostgreSQL10Dialect**

Dies hat mich mit der DB verbunden

Es ist nicht so seltsam, weil Springboot die Versionsabhängigkeit selbst übernimmt und die Entwicklungsarbeit reduziert. Auf der anderen Seite verschwendet Springboot viele Stunden, wenn es eine falsche Abhängigkeit wählt.

Abhigyan Chatterjee
quelle
0
Use this Sample code

application.properties
# DataSource settings: set here your own configurations for the database 
# connection. In this example we have "dojsb" as database name and 
# "root" as username and password.
spring.datasource.url =jdbc:postgresql://localhost:5432/usman
spring.datasource.username = postgres
spring.datasource.password = 12345

# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1

# Show or not log for each sql query
spring.jpa.show-sql = true

# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = create

# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy

# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

server.port = 8963



Entity Class:



import java.sql.Timestamp;
import java.util.UUID;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Type;


@Entity
@Table(name = "QUEUERECORDS")
public class QueuesRecords {
    @Id
    private UUID id;

    @Column(name="payload", nullable = true)
    @Type(type="text")
    private String payload;


    @Column(name="status", nullable = true)
    @Type(type="text")
    private String status;

    private Timestamp starttime;

    private Timestamp endtime;

    @Column(name="queueid",nullable= true)
    @Type(type="text")
    private String queueid;

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public String getPayload() {
        return payload;
    }

    public void setPayload(String payload) {
        this.payload = payload;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Timestamp getStarttime() {
        return starttime;
    }

    public void setStarttime(Timestamp starttime) {
        this.starttime = starttime;
    }

    public Timestamp getEndtime() {
        return endtime;
    }

    public void setEndtime(Timestamp endtime) {
        this.endtime = endtime;
    }

    public String getQueueid() {
        return queueid;
    }

    public void setQueueid(String queueid) {
        this.queueid = queueid;
    }



}



Main class



import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class Test{

    public static void main(String[] args) {

        SpringApplication.run(Test.class, args);


    }
}
Usman Yaqoob
quelle
0

Ganz einfach, wir fügen ein Semikolon hinzu, nach
spring.jpa.hibernate.ddl-auto = create;
dem es falsch
spring.jpa.hibernate.ddl-auto = create
genug ist

Ansar Mohamed
quelle
0

Wenn Ihre Datenbank MySQL ist:

spring.jpa.hibernate.ddl-auto=update
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/your_database
spring.datasource.username=root
spring.datasource.password=root

Wenn Ihre Datenbank PostgreSQL ist:

spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:postgresql://localhost:3306/your_database
spring.datasource.username=root
spring.datasource.password=root
Wendell Tufano
quelle
0

Die folgenden Konfigurationen haben bei mir funktioniert:

spring.jpa.properties.javax.persistence.schema-generation.database.action=create
spring.jpa.properties.javax.persistence.schema-generation.create-database-schemas=true
spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
spring.jpa.properties.javax.persistence.schema-generation.drop-source=metadata
spring.jpa.properties.javax.persistence.schema-generation.connection=jdbc:mysql://localhost:3306/your_database
Daniel Reis
quelle
0

Wenn Sie dieses Problem bei Spring Boot hatten, überprüfen Sie Ihre Paketnamen, die genau so aussehen sollten:

com.example.YOURPROJECTNAME - consists main application class
com.example.YOURPROJECTNAME.entity - consists entities
Erdem İnanç
quelle
Können Sie einige Referenzen angeben, die besagen, dass dies eine Voraussetzung ist? Das erhöht den Wert Ihrer Antwort.
Ganesh Satpute
0

So stellen Sie mit Springboot eine Verbindung zu MySQL her und erstellen automatisch eine Tabelle in der Datenbank: spring.datasource.url=jdbc:mysql://localhost:3306/solace spring.datasource.username=root spring.datasource.password=root spring.jpa.generate-ddl=true spring.jpa.hibernate.ddl-auto=update

Shivam Singh
quelle
2
Bitte beschreiben Sie genauer, was Sie tun, um dieses Ergebnis zu erzielen und woher Sie wissen, dass es korrekt ist :)
Lars Nielsen
-2

Ich hatte das gleiche Problem und löste es nur mit diesem Add:

spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
Djuka
quelle
2
Postgres hilft nicht mit der MySQL-Datenbank.
Gann14
-3

Einfach hinzufügen

spring.jpa.databaseplatform=org.hibernate.dialect.PostgreSQLDialect  

Am Ende. Dies wird Ihr Problem lösen. Nur das fehlte

Saurabh Agrawal
quelle
1
Postgres hilft nicht mit der MySQL-Datenbank.
Gann14