简体   繁体   中英

ERROR: Cannot add or update a child row: a foreign key constraint fails in hibernate using mysql

i need help in one to many mapping with FROM INDEX.Java and many to one mapping from the requirement.

I get the following error when i run my demo.java

INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Jan 01, 2014 11:55:49 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
Jan 01, 2014 11:55:49 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select max(pid) from project
Hibernate: insert into project (deadline, email, pname, password, pid) values (?, ?, ?, ?, ?)
Hibernate: insert into requirement (ar, fr, nfr, description, pid, rname, rid) values (?, ?, ?, ?, ?, ?, ?)
Jan 01, 2014 11:55:50 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1452, SQLState: 23000
Jan 01, 2014 11:55:50 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Cannot add or update a child row: a foreign key constraint fails (`proj`.`requirement`, CONSTRAINT `requirement_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `project` (`pid`))
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`proj`.`requirement`, CONSTRAINT `requirement_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `project` (`pid`))

this is the error log that i get

  package proj;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.GenericGenerator;

@Entity @Table(name="project")
public class Index {
    int pid;
    String name;
    String email;
    String password;
    String deadline;
    private transient List<Requirment> Requirment;

    public Index() {
        // TODO Auto-generated constructor stub
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setPid(int pid) {
        this.pid = pid;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public void setDeadline(String deadline) {
        this.deadline = deadline;
    }
    public void setRequirment(List<Requirment> requirment) {
        Requirment = requirment;
    }

    /////////////////////////////////////////////
    @Column (name="pname")
    public String getName() {
        return name;
    }
    @Id
    @GeneratedValue(generator="increment")
    @GenericGenerator(name="increment", strategy = "increment")
    @Column(name = "pid")
    public int getPid() {
        return pid;
    }
    @Column (name="deadline")
    public String getDeadline() {
        return deadline;
    }
    @Column (name="email")
    public String getEmail() {
        return email;
    }
    @Column (name="password")
    public String getPassword() {
        return password;
    }
    @OneToMany(fetch=FetchType.EAGER, mappedBy="ind")
    //@Cascade({org.hibernate.annotations.CascadeType.ALL})
    public List<Requirment> getRequirment() {
        return Requirment;
    }

}

THIS IS THE INDEX.JAVA

    import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.GenericGenerator;

@Entity @Table(name="requirement")
public class Requirment {
    int pid;
    int rid;
    String rname;
    String desp;
    boolean FR;
    boolean NFR;
    boolean AR;
    private transient Index ind;

    public void setAR(boolean aR) {
        AR = aR;
    }
    public void setDesp(String desp) {
        this.desp = desp;
    }
    public void setFR(boolean fR) {
        FR = fR;
    }
    public void setNFR(boolean nFR) {
        NFR = nFR;
    }
    public void setPid(int pid) {
        this.pid = pid;
    }
    public void setRid(int rid) {
        this.rid = rid;
    }
    public void setRname(String rname) {
        this.rname = rname;
    }
    public void setInd(Index ind) {
        this.ind = ind;
    }

    public Requirment() {
        // TODO Auto-generated constructor stub
    }


    @Column (name="description")
    public String getDesp() {
        return desp;
    }
    @Column (name="pid")
    public int getPid() {
        return pid;
    }
    @Column (name="rname")
    public String getRname() {
        return rname;
    }
    @Id
    @Column (name="rid")
    public int getRid() {
        return rid;
    }
    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="pid", nullable=false, insertable=false, updatable=false)
    public Index getInd() {
        return ind;
    }

    @Column (name="fr")
    public boolean getFR() {
        return this.FR;
    }
    @Column (name="ar")
    public boolean getAR() {
        return this.AR;
    }
    @Column (name="nfr")
    public boolean getNFR() {
        return this.NFR;
    }

}

THIS IS REQUIREMENT.JAVA

public class demo {

    public static void main(String[] args) 
    {
        Index temp=new Index();
        //temp.setPid(9);
        temp.setName("SRE");
        temp.setEmail("123@hotmail.com");
        temp.setPassword("1234");
        temp.setDeadline("20/12/13");


        //DataAccessUtil.del(Index.class, 1);
        Requirment req=new Requirment();
        req.setInd(temp);
        req.setPid(temp.pid);
        req.setAR(false);
        req.setNFR(false);
        req.setFR(true);
        req.setRname("testing");
        req.setDesp("testing phase at night");
        req.setRid(1);
        DataAccessUtil.save(temp);
        //temp.getRequirment().add(req);
        DataAccessUtil.save(req);

    }


}

this is demo.java

    create database project;
use project;

create table project( pid int(4) PRIMARY KEY, password varchar(50) , pname varchar(50), email varchar(50) , deadline varchar(50));

create table requirement( pid int(4) NOT NULL, rid int(4), rname text, description text, fr
tinyint(1), nfr tinyint(1),  ar tinyint(1), FOREIGN KEY (pid) REFERENCES project(pid)
        ON DELETE CASCADE );

THIS IS SQL SCRIPT

How can it work if you declared the Requirement.ind @ManyToOne association with insertable=false, updatable=false ? That essentially means it's read only.

I see the pid primitive for that column also but in your example you're setting req.setPid(temp.pid) before temp is actually saved. So it doesn't make any sense.

You can have the following solutions:

  1. Remove insertable=false, updatable=false from the Requirement.ind @ManyToOne association. Remove the Requirement.pid property cause it seems that it doesn't make any sense at all (you can always use Requirement.ind.getPid).
  2. Use the req.setPid(temp.pid); but after temp is saved (ie temp.pid is assigned)

在Index bean中,使用many to one关联的用法是

@ManyToOne(fetch=FetchType.EAGER,cascade = CascadeType.ALL)

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