javapostgresqlspring-bootapipgadmin

insert or update on table "products" violates foreign key (Postgresql spring boot) error


I have an api in spring boot and I decided to create a model order, but I found some database errors and I decided to enter my pg admin and delete all the tables and start over, but now when I request my model product I find the error:

2023-03-27T15:00:48.189-03:00  WARN 31677 --- [nio-8011-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 23503
2023-03-27T15:00:48.190-03:00 ERROR 31677 --- [nio-8011-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: insert or update on table "products" violates foreign key constraint "fkselc31gul05wygg2llkv0v3yb"
  Detail: Key (product_id)=(9c2655d0-c5a4-45f1-ba97-8b5fe1a385d8) is not present in table "orders".
2023-03-27T15:00:48.231-03:00  INFO 31677 --- [nio-8011-exec-6] o.h.e.j.b.internal.AbstractBatchImpl     : HHH000010: On release of batch it still contained JDBC statements

I already tried to remove all the tables, I also tried to create another database and delete the old one, but I still get the same error

orderModel

package com.api.business_manager_api.Models;

import jakarta.persistence.*;

import java.util.List;
import java.util.UUID;

@Entity
@Table(name = "ORDERS")
public class OrderModel {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID order_id;
    @ManyToOne
    @JoinColumn(name = "customer_id")
    private CustomerModel customer;
    @OneToMany
    @JoinColumn(name = "product_id")
    private List<ProductModel> products;
    @Column(nullable = false, length = 80)
    private Float totalAmount;

    public UUID getOrder_id() {
        return order_id;
    }

    public void setOrder_id(UUID order_id) {
        this.order_id = order_id;
    }

    public CustomerModel getCustomer() {
        return customer;
    }

    public void setCustomer(CustomerModel customer) {
        this.customer = customer;
    }

    public List<ProductModel> getProducts() {
        return products;
    }

    public void setProducts(List<ProductModel> products) {
        this.products = products;
    }

    public Float getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(Float totalAmount) {
        this.totalAmount = totalAmount;
    }
}

productModel

package com.api.business_manager_api.Models;

import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;

import java.util.UUID;

@Entity
@Table(name = "PRODUCTS")
public class ProductModel {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID product_id;

    @Column(nullable = false, length = 80)
    private String product;
    @Column(nullable = true, length = 200)
    private String image_url;
    @Column(nullable = true, length = 80)
    private String brand;
    @Column(nullable = true, length = 80)
    private String description;
    @Column(nullable = true, length = 80)
    private Float price;

    @Column(nullable = true, length = 80)
    private Float extraPrice;

    @Column(nullable = false, length = 80)
    private Integer stock;
    @JsonIgnore
    @ManyToOne
    @JoinColumn(name = "category_id")
    private CategoryModel productCategory;

    public UUID getProduct_id() {
        return product_id;
    }

    public void setProduct_id(UUID product_id) {
        this.product_id = product_id;
    }

    public String getProduct() {
        return product;
    }

    public void setProduct(String product) {
        this.product = product;
    }

    public String getImage_url() {
        return image_url;
    }

    public void setImage_url(String image_url) {
        this.image_url = image_url;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public Integer getStock() {
        return stock;
    }

    public void setStock(Integer stock) {
        this.stock = stock;
    }

    public CategoryModel getProductCategory() {
        return productCategory;
    }

    public void setProductCategory(CategoryModel productCategory) {
        this.productCategory = productCategory;
    }

    public Float getExtraPrice() {
        return extraPrice;
    }

    public void setExtraPrice(Float extraPrice) {
        this.extraPrice = extraPrice;
    }
}

I don't know what the reaction would be, because as you guys can see, my product doesn't depend on anything order to be created

update!

postman return:

{
    "order_id": "982f2270-28fa-4dcf-ba24-89b2c9f18bb5",
    "customer": {
        "customer_id": "c33d4cf7-a931-4818-8d86-94b6c56b9426",
        "name": "Antoni Ancelotti",
        "description": "italian",
        "cellphone": "21 8494944",
        "email": "ancelotti@email.com",
        "note": "ok"
    },
    "products": [
        {
            "product_id": "47b0a1ff-71e7-4b08-a243-9cf01ff55af7",
            "product": null,
            "image_url": null,
            "brand": null,
            "description": null,
            "price": null,
            "extraPrice": null,
            "stock": null
        },
        {
            "product_id": "47b0a1ff-71e7-4b08-a243-9cf01ff55af7",
            "product": "Galaxy A13 128 GB Slim",
            "image_url": "/products/images/e40989d2-66g8-4531-be26-00c124a8dfd6-SM-A136UZRAATT-8.webp",
            "brand": null,
            "description": "galaxy",
            "price": 50.0,
            "extraPrice": null,
            "stock": 50
        }
    ],
    "totalAmount": 1800.0
}

Solution

  • I believe what you are trying to do here is to establish a unidirectional one-to-many relationship between ORDERS and PRODUCTS table i.e. one order may be having multiple products. So ideally your join column should be something like order_id rather than product_id since that would be the FK in PRODUCTS table referring to the order_id entries of ORDERS table. After, changing the Join column, you can also add cascading so that changes in ORDERS table are cascaded according to your use case to PRODUCTS table as well.

    Here are some good references you can use for reference on creating unidirectional One-To-Many relationship using Hibernate and Springboot.

    https://www.bezkoder.com/jpa-one-to-many-unidirectional/

    Furthermore, if you want orders info in ProductModel Objects I would recommend you to create a OneToMany bidirectional relationship using OrderModel member in ProductModel Class.