简体   繁体   中英

Cannot add or update a child row: a foreign key constraint fails hibernate with mysql

I'm new to hibernate and trying to run a sample program. But when I run the program it throws error as Cannot add or update a child row: a foreign key constraint fails ( tel . customer , CONSTRAINT customer_ibfk_1 FOREIGN KEY ( transaction_id ) REFERENCES transaction ( id )). I'm using annotation for mapping entity class.

MySQL script

create table transaction ( id int not null auto_increment, txn_date date not null, txn_total decimal(15,3) not null, primary key(id) );

create table customer ( id int not null auto_increment, transaction_id int not null, cust_name varchar(50) not null, cust_email varchar(50) null, cust_address varchar(100) null, primary key(id), constraint customer_ibfk_1 foreign key ( transaction_id ) references transaction ( id ) );

Customer.java file looks like this

   package com.sachin.entity;
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;

    @Entity
    @Table(name="customer")
    public class Customer {

    @Id
    @Column(name="id")
    private int id;

    @Column(name="transaction_id",updatable = false,insertable = 
    false)
    private int transaction_id;

    @Column(name="cust_name")
    private String cust_name;

    @Column(name="cust_email")
    private String cust_email;

    @Column(name="cust_address")
    private String cust_address;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name ="transaction_id")
    private Transaction transaction;


    public Customer()
    {

    }


    public Customer(int transaction_id, String cust_name, String cust_email, String cust_address,
            Transaction transaction) {
        super();
        this.transaction_id = transaction_id;
        this.cust_name = cust_name;
        this.cust_email = cust_email;
        this.cust_address = cust_address;
        this.transaction = transaction;
    }


    public int getId() {
        return id;
    }


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


    public int getTransaction_id() {
        return transaction_id;
    }


    public void setTransaction_id(int transaction_id) {
        this.transaction_id = transaction_id;
    }


    public String getCust_name() {
        return cust_name;
    }


    public void setCust_name(String cust_name) {
        this.cust_name = cust_name;
    }


    public String getCust_email() {
        return cust_email;
    }


    public void setCust_email(String cust_email) {
        this.cust_email = cust_email;
    }


    public String getCust_address() {
        return cust_address;
    }


    public void setCust_address(String cust_address) {
        this.cust_address = cust_address;
    }


    public Transaction getTransaction() {
        return transaction;
    }


    public void setTransaction(Transaction transaction) {
        this.transaction = transaction;
    }


    @Override
    public String toString() {
        return "Customer [id=" + id + ", transaction_id=" + transaction_id + ", cust_name=" + cust_name
                + ", cust_email=" + cust_email + ", cust_address=" + cust_address + ", transaction=" + transaction
                + "]";
    }
}

My Transaction.java file looks like this

    package com.sachin.entity;
    import java.util.Date;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    import org.hibernate.annotations.Cascade;
    import org.hibernate.annotations.CascadeType;

    @Entity
    @Table(name="transaction")
    public class Transaction {

    @Id
    @Column(name="id")
    private int id;

    @Column(name="txn_date")
    private Date txn_date;

    @Column(name="txn_total")
    private double txn_total;

    @OneToOne(mappedBy = "transaction")
    private Customer customer;

    public Transaction()
    {

    }

    public Transaction(Date txn_date, double txn_total, Customer customer) {
        super();
        this.txn_date = txn_date;
        this.txn_total = txn_total;
        this.customer = customer;
    }

    public int getId() {
        return id;
    }

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

    public Date getTxn_date() {
        return txn_date;
    }

    public void setTxn_date(Date txn_date) {
        this.txn_date = txn_date;
    }

    public double getTxn_total() {
        return txn_total;
    }

    public void setTxn_total(double txn_total) {
        this.txn_total = txn_total;
    }

    public Customer getCustomer() {
        return customer;
    }

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

    @Override
    public String toString() {
        return "Transaction [id=" + id + ", txn_date=" + txn_date + ", txn_total=" + txn_total + ", customer="
                + customer + "]";
    }
}

My Main.java file looks like this

package com.sachin.hibernate;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.sachin.entity.Customer;
import com.sachin.entity.Transaction;
import com.sachin.utility.HibernateUtillity;

public class Main {


    public static void main(String[] args) {

        SessionFactory sessionFactory = null;
        Session session = null;


        try 
        {
            sessionFactory = HibernateUtillity.getSessionFactory();
            session = sessionFactory.getCurrentSession();
            System.out.println("Session Created using Annotation");

            session.beginTransaction();
            System.out.println("Transaction Started");

            Customer customer = new Customer();

            customer.setCust_name("Sachin");
            customer.setCust_email("sachinmukherjee29@gmail.com");
            customer.setCust_address("Bhavdhan Pune");

            Transaction transaction = new Transaction();
            transaction.setTxn_date(new Date());
            transaction.setTxn_total(1000.256);

            transaction.setCustomer(customer);
            customer.setTransaction(transaction);


            session.save(customer);

            session.getTransaction().commit();
            System.out.println("Saved!!!!!!!!!");
        }catch (Exception e) {
            System.out.println("Exception Occured");
            e.printStackTrace();
        }finally {
            if(sessionFactory != null && !sessionFactory.isClosed())
            {
                System.out.println("Closing Session Factory");
                sessionFactory.close();
            }
        }
    }
}

My SQL logs looks like this

Session Created using Annotation
Transaction Started
Hibernate: select transactio_.id, transactio_.txn_date as txn_date2_1_, transactio_.txn_total as txn_tota3_1_ from transaction transactio_ where transactio_.id=?
Hibernate: insert into transaction (txn_date, txn_total, id) values (?, ?, ?)
Hibernate: insert into customer (cust_address, cust_email, cust_name, transaction_id, id) values (?, ?, ?, ?, ?)

This error might be occurring because one or more records in the customer table is referring to a record in the transaction table which does not exist. You may check for this directly against MySQL with the following query:

SELECT *
FROM customer c
WHERE NOT EXISTS (SELECT 1 FROM transaction t WHERE t.id = c.transaction_id);

If the above query returns anything other than an empty result set, then it means you have dangling customer records which are not properly referring back to the transaction table. In that case, you should fix your data, then restart your application.

@Column(name="transaction_id",updatable = false, insertable = false ) private int transaction_id;

This looks weird to me.

Ideally Customer entity should be able to add and update transaction details.

Relation between Customer and Transaction is Customer HAS transactions. So in my opinion, Customer entity is owning this relationship.

Please cross check this insertable and updatable false if they are in right entity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM