onetomany單向一對多java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails ()


2020-9-1更新:

一方的外鍵字段寫錯了。

導致外鍵和多方的主鍵重名

下邊是正確的一方的外鍵

  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "poolid")//stockpool中該字段為外鍵,股票表中指向本表的外鍵名稱
    public Set<Stock> getStocks() {
        return stocks;
    }

    public void setStocks(Set<Stock> stocks) {
        this.stocks = stocks;
    }

對比一下原來一方中錯誤的外鍵

  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "id")//stockpool中該字段為外鍵,股票表中指向本表的外鍵名稱
    public Set<Stock> getStocks() {
        return stocks;
    }

    public void setStocks(Set<Stock> stocks) {
        this.stocks = stocks;
    }

找到原因了吧?就偷了個懶,把所有的id都簡單寫為id,所以就出問題了,多方中本來就有id,而且還是主鍵,一方中又想指派一個外鍵叫做id,那就掛掉了。所以有時候少打幾個字母,效率不僅不會高,而且還會翻車

修復之后,問題解決,成功向數據庫插入數據

 

 

非常奇怪的一個問題: 單向一對多,一方管理。只能插入一條數據,第二條數據就無法插入

如下為一方

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hs.model;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
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.GenericGenerator;

/**
 *
 * @author wishr
 */
@Entity
@Table(name = "t_stockpoolding")
public class StockPool implements Serializable {

    private int id;
    private String name;
    private String description;
    private Timestamp createDt;
    private Set<Stock> stocks = new HashSet<>();

    @Id
    @GeneratedValue(generator = "_native")
    @GenericGenerator(name = "_native", strategy = "native")
    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

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

    public Timestamp getCreateDt() {
        return createDt;
    }

    public void setCreateDt(Timestamp createDt) {
        this.createDt = createDt;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "id")//stockpool中該字段為外鍵,股票表中指向本表的外鍵名稱
    public Set<Stock> getStocks() {
        return stocks;
    }

    public void setStocks(Set<Stock> stocks) {
        this.stocks = stocks;
    }

}

 

 如下為多方,很簡單,一個股票池中有很多股票,我找到一個股票池,就可以找到一堆股票,我可以向股票池添加股票,也可以從股票池刪除股票,也可以刪除股票池以全部刪除股票,但是至於哪個股票在哪個股票池,我不關心

典型的一對多,單向

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hs.model;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;

/**
 *
 * @author wishr
 */
@Entity
@Table(name = "t_stockding")
public class Stock implements Serializable {

    private int id;
    private String stockCode;
    private String stockName;

    @Id
    @GeneratedValue(generator = "_native")
    @GenericGenerator(name = "_native", strategy = "native")
    public int getId() {
        return id;
    }

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

    public String getStockCode() {
        return stockCode;
    }

    public void setStockCode(String stockCode) {
        this.stockCode = stockCode;
    }

    public String getStockName() {
        return stockName;
    }

    public void setStockName(String stockName) {
        this.stockName = stockName;
    }

}

 

 再來看服務層代碼,省略掉一些無關緊要的代碼

  StockPool sp = spd.getByName(session, poolname);//從數據庫中查到要操作的股票池

 

 

  Set<Stock> stocksInPool = sp.getStocks();//從股票池中拿出股票列表

 

 stocksInPool.add(stockWhichOnDealing);//給當前股票池加入這個股票   

 

sp.setStocks(stocksInPool);//更新該股票池的股票集合
spd.update(session, sp);//持久化

 

然后再省略一些無關緊要的事務操作。

如果第一次添加,是沒問題的

數據表刪干凈

 

首先創建一個股票池

 

表也自動創建完成

 

向股票池中添加一個股票,成功

 

 debug數據正常

 

 持久化后也正常

 

 然后我重新添加一個

這就不行了,報錯了

java.sql.SQLIntegrityConstraintViolationException: 
Cannot add or update a child row: a foreign key constraint fails 
(`networth_ding`.`t_stockding`, CONSTRAINT `FK_pi66wsimny0t01abiw8wm5ql9` FOREIGN KEY (`id`) REFERENCES `t_stockpool` (`id`))

 

 

 百撕不得騎姐!!!

為什么,第二次再保存,為什么就不行了呢?而且也定位不到問題,好愁人

 

 

 

z


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM