Spring Boot: Flyway: 模式验证:缺少表 [products]
我在尝试将Flyway集成进来进行数据库迁移,但现在卡在一个错误上。我大致认为错误信息是:架构验证失败:缺少表 [products]。我在resources/db下有两个SQL文件。起初我把它放在resources/db/migrations里,但在IDE中显示的路径是db.migrations,于是想到把它移动到db/。路径已在application.properties中更新。仍然不清楚该如何修复。我尝试了chatgpt/gemini提到的几种方法,但都没有成功。
V1__create_users_table.sql
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE
);
V2__create_products_table.sql
CREATE TABLE products (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
price DOUBLE NOT NULL,
user_id BIGINT NOT NULL,
CONSTRAINT fk_products_user
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
);
application.properties
spring.application.name=demo
# The location of your database (change 'my_db' to your actual database name)
spring.datasource.url=jdbc:mysql://localhost:3306/my_db
# Your MySQL credentials
spring.datasource.username=root
spring.datasource.password=****
# The Driver class (Spring usually finds this, but being explicit helps)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Hibernate should only validate (NOT create)
spring.jpa.hibernate.ddl-auto=validate
# Optional but recommended
spring.jpa.show-sql=true
# Flyway
spring.flyway.enabled=true
spring.flyway.locations=classpath:db
#spring.flyway.baseline-on-migrate=true
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name/>
<description/>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>26</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
User entity
package com.example.demo.user;
import com.example.demo.products.Product;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
@NotBlank(message = "Name is required")
@Size(min = 3, max = 20, message = "Name must be between 3 and 20 characters")
private String name;
@Column(unique = true, nullable = false)
private String email;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JsonManagedReference
private List<Product> products = new ArrayList<>();
public User() {} // Required by JPA
public User(String name, String email, List<Product> products) {
this.name = name;
this.email = email;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public void setProducts(List<Product> products) {
this.products = products;
if (products != null) {
// Link the parent (this User) to every child (Product)
for (Product p : products) {
p.setUser(this);
}
}
}
public List<Product> getProducts() {
return this.products;
}
}
Product entity
package com.example.demo.products;
import com.example.demo.user.User;
import com.fasterxml.jackson.annotation.JsonBackReference;
import jakarta.persistence.*;
@Entity
@Table(name = "products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private double price;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
@JsonBackReference
private User user;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
public void setUser(User user) {
this.user = user;
}
}
解决方案
在Spring Boot 4.x中,你需要使用Flyway Starter,相比手动添加依赖要简单得多
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-flyway</artifactId>
</dependency>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。