繁体   English   中英

无法添加或更新子行:外键约束失败 hibernate 和 mysql

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

我是 hibernate 的新手并尝试运行示例程序。 但是当我运行程序时,它会抛出错误,因为无法添加或更新子行:外键约束失败( telcustomer ,约束customer_ibfk_1 _ibfk_1外键( transaction_id _id)引用transactionid ))。 我正在使用注释映射实体 class。

MySQL 脚本

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 文件看起来像这样

   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
                + "]";
    }
}

我的 Transaction.java 文件看起来像这样

    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 + "]";
    }
}

我的 Main.java 文件看起来像这样

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();
            }
        }
    }
}

我的 SQL 日志看起来像这样

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 (?, ?, ?, ?, ?)

发生此错误的原因可能是customer表中的一条或多条记录引用了transaction表中不存在的记录。 您可以使用以下查询直接针对 MySQL 进行检查:

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

如果上述查询返回空结果集以外的任何内容,则意味着您有未正确引用transaction表的悬空客户记录。 在这种情况下,您应该修复您的数据,然后重新启动您的应用程序。

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

这对我来说看起来很奇怪。

理想情况下,客户实体应该能够添加和更新交易细节。

Customer 和 Transaction 之间的关系是 Customer HAS 事务。 所以在我看来,客户实体拥有这种关系。

如果它们在正确的实体中,请交叉检查这个可插入和可更新的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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