ARTICLE AD BOX
I was trying to integrate flyway to do migrations and now I am stuck at an error. I think it basically says Schema validation: missing table [products]. I have 2 .sql files under resources/db. I kept it under resources/db/migrations initially but since file path showed db.migrations in IDE, though of moving it to db. Path is updated in application.properties. Could not understand how to fix this. Tried out several things mentioned by chatgpt/gemini but no luck.
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=truepom.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; } }