簡體   English   中英

Hibernate @OneToOne 無法添加或更新子行:外鍵約束

[英]Hibernate @OneToOne cannot add or update a child row: a foreign key constraint

我正在使用 JPA、Hibernate、Spring 和 MySQL

無法添加或更新子行:外鍵約束失敗( db1 ,CONSTRAINT stock_detail FOREIGN KEY( FK_STOCK_ID )REFERENCES stockSTOCK_ID STOCK_ID

創建腳本

 CREATE TABLE IF NOT EXISTS `stock` (
  `STOCK_ID` int(10) unsigned NOT NULL,
  `STOCK_CODE` varchar(10) NOT NULL,
  `STOCK_NAME` varchar(20) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=86 DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `stock_detail` (
  `STOCK_ID` int(10) unsigned NOT NULL,
  `COMP_NAME` varchar(100) NOT NULL,
  `COMP_DESC` varchar(255) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=72 DEFAULT CHARSET=utf8;

ALTER TABLE `stock`
  ADD PRIMARY KEY (`STOCK_ID`) USING BTREE,
  ADD UNIQUE KEY `UNI_STOCK_NAME` (`STOCK_NAME`),
  ADD UNIQUE KEY `UNI_STOCK_CODE` (`STOCK_CODE`) USING BTREE;

ALTER TABLE `stock_detail`
  ADD PRIMARY KEY (`STOCK_ID`) USING BTREE;

ALTER TABLE `stock`
  MODIFY `STOCK_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=86;

ALTER TABLE `stock_detail`
  MODIFY `STOCK_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=72;

ALTER TABLE `stock_detail`
  ADD CONSTRAINT `FK_STOCK_ID` FOREIGN KEY (`STOCK_ID`) REFERENCES `stock` (`STOCK_ID`);

股票實體

@Entity
@Table(name = "stock")
@XmlRootElement
@Component("astock")
@NamedQueries({
    @NamedQuery(name = "Stock.findAll", query = "SELECT s FROM Stock s"),
    @NamedQuery(name = "Stock.findByStockId", query = "SELECT s FROM Stock s WHERE s.stockId = :stockId"),
    @NamedQuery(name = "Stock.findByStockCode", query = "SELECT s FROM Stock s WHERE s.stockCode = :stockCode"),
    @NamedQuery(name = "Stock.findByStockName", query = "SELECT s FROM Stock s WHERE s.stockName = :stockName")})
public class Stock implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "STOCK_ID")
    private Integer stockId;
    @Basic(optional = false)

    @Size(min = 1, max = 10)
    @Column(name = "STOCK_CODE")
    private String stockCode;
    @Basic(optional = false)

    @Size(min = 1, max = 20)
    @Column(name = "STOCK_NAME")
    private String stockName;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "stock")
    private StockDetail stockDetail;

StockDetail實體

@Entity
@Table(name = "stock_detail")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "StockDetail.findAll", query = "SELECT s FROM StockDetail s"),
    @NamedQuery(name = "StockDetail.findByStockId", query = "SELECT s FROM StockDetail s WHERE s.stockId = :stockId"),
    @NamedQuery(name = "StockDetail.findByCompName", query = "SELECT s FROM StockDetail s WHERE s.compName = :compName"),
    @NamedQuery(name = "StockDetail.findByCompDesc", query = "SELECT s FROM StockDetail s WHERE s.compDesc = :compDesc")})
public class StockDetail implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "STOCK_ID")
    private Integer stockId;
    @Basic(optional = false)

    @Size(min = 1, max = 100)
    @Column(name = "COMP_NAME")
    private String compName;

    @Basic(optional = false)
    @Size(min = 1, max = 255)
    @Column(name = "COMP_DESC")
    private String compDesc;
    @JoinColumn(name = "STOCK_ID", referencedColumnName = "STOCK_ID")
    @OneToOne(cascade = CascadeType.ALL)
    private Stock stock;

我是如何努力挽救它的。

    Stock StockServices = (Stock) applicationContext.getBean("astock");

    Stock stock = new Stock();
    stock.setStockCode("123");
    stock.setStockName("AAPL");

    StockDetail stockDetail = new StockDetail();
    stockDetail.setCompName("Apple");
    stockDetail.setCompDesc("A hardware and software company");

    stockDetail.setStock(stock);
    stock.setStockDetail(stockDetail);

    sessionFactory.getCurrentSession().saveOrUpdate(stock);

同意接受的答案。

不過,如果您想在子表中堅持使用外鍵作為主鍵,請在子表上使用Foreign Key Generator 這樣,我們可以減少創建太多唯一ID所需的數據庫引擎開銷。

請參閱: ForeignKeyGeneratorUsage

你的問題是,您嘗試使用stock_detail.STOCK_ID既作為PRIMARY KEYstock_detailFOREIGN KEY從股市和你為他們分配不同的自動遞增值。

當Hibernate保存它們時,它將嘗試保存STOCK_ID =86 stock_detailSTOCK_ID=72 stock_detail ,這會破壞外鍵合同。

而是在您的stock_detail表中創建一個單獨的主鍵,例如stock_detail_id並將stock_id為單獨的列。

接受的答案沒有提供最佳解決方案。 出於此處概述的原因,應保留使用stock.STOCK_ID作為stock_detail的主/外鍵的方法。 在 JPA 中,也支持這種方法,只需使用本教程第 4 節中概述的@PrimaryKeyJoinColumn@MapsId注釋

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM