【问题标题】:Hibernate oracle integrity constraint violated违反了 Hibernate oracle 完整性约束
【发布时间】:2011-08-12 07:23:01
【问题描述】:

我遇到了通过休眠映射 oracle 的问题

我有这些课程

Stock.java

    package com.mc.stock;

    import java.util.HashSet;
    import java.util.Set;
    import javax.persistence.Basic;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.SequenceGenerator;
    import javax.persistence.Table;
    import javax.persistence.UniqueConstraint;

    @Entity
    @Table(name = "stock", uniqueConstraints = {
        @UniqueConstraint(columnNames = "STOCK_NAME"),
        @UniqueConstraint(columnNames = "STOCK_CODE")})
    public class Stock implements java.io.Serializable {

        private Integer stockId;
        private String stockCode;
        private String stockName;
        private Set<StockDailyRecord> stockDailyRecords = new HashSet<StockDailyRecord>(
            0);

        public Stock() {
        }

        public Stock(String stockCode, String stockName) {
            this.stockCode = stockCode;
            this.stockName = stockName;
        }

        public Stock(String stockCode, String stockName,
            Set<StockDailyRecord> stockDailyRecords) {
            this.stockCode = stockCode;
            this.stockName = stockName;
            this.stockDailyRecords = stockDailyRecords;
        }

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_stock_id")
        @SequenceGenerator(name = "seq_stock_id", sequenceName = "seq_stock_id", initialValue = 1, allocationSize = 1)
        @Basic(optional = false)
        @Column(name = "STOCK_ID", unique = true, nullable = false)
        public Integer getStockId() {
            return this.stockId;
        }

        public void setStockId(Integer stockId) {
            this.stockId = stockId;
        }

        @Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
        public String getStockCode() {
            return this.stockCode;
        }

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

        @Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
        public String getStockName() {
            return this.stockName;
        }

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

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock")
        public Set<StockDailyRecord> getStockDailyRecords() {
            return this.stockDailyRecords;
        }

        public void setStockDailyRecords(Set<StockDailyRecord> stockDailyRecords) {
            this.stockDailyRecords = stockDailyRecords;
        }
    }

StockDailyRecord.java

    package com.mc.stock;

    import java.util.Date;
    import javax.persistence.Basic;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.SequenceGenerator;
    import javax.persistence.Table;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    import javax.persistence.UniqueConstraint;

    @Entity
    @Table(name = "stock_daily_record", uniqueConstraints = @UniqueConstraint(columnNames = "DATEX"))
    public class StockDailyRecord implements java.io.Serializable {

        private Integer recordId;
        private Stock stock;
        private Integer priceOpen;
        private Integer priceClose;
        private Integer priceChange;
        private Long volume;
        private Date date;

        public StockDailyRecord() {
        }

        public StockDailyRecord(Stock stock, Date date) {
            this.stock = stock;
            this.date = date;
        }

        public StockDailyRecord(Stock stock, Integer priceOpen, Integer priceClose,
                Integer priceChange, Long volume, Date date) {
            this.stock = stock;
            this.priceOpen = priceOpen;
            this.priceClose = priceClose;
            this.priceChange = priceChange;
            this.volume = volume;
            this.date = date;
        }



        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_daily_record")
        @SequenceGenerator(name = "seq_daily_record", sequenceName = "seq_daily_record", initialValue = 1, allocationSize = 1)
        @Basic(optional = false)
        @Column(name = "RECORD_ID", unique = true, nullable = false)
        public Integer getRecordId() {
            return this.recordId;
        }

        public void setRecordId(Integer recordId) {
            this.recordId = recordId;
        }

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "STOCK_ID", nullable = false)
        public Stock getStock() {
            return this.stock;
        }

        public void setStock(Stock stock) {
            this.stock = stock;
        }

        @Column(name = "PRICE_OPEN", precision = 6)
        public Integer getPriceOpen() {
            return this.priceOpen;
        }

        public void setPriceOpen(Integer priceOpen) {
            this.priceOpen = priceOpen;
        }

        @Column(name = "PRICE_CLOSE", precision = 6)
        public Integer getPriceClose() {
            return this.priceClose;
        }

        public void setPriceClose(Integer priceClose) {
            this.priceClose = priceClose;
        }

        @Column(name = "PRICE_CHANGE", precision = 6)
        public Integer getPriceChange() {
            return this.priceChange;
        }

        public void setPriceChange(Integer priceChange) {
            this.priceChange = priceChange;
        }

        @Column(name = "VOLUME")
        public Long getVolume() {
            return this.volume;
        }

        public void setVolume(Long volume) {
            this.volume = volume;
        }

        @Temporal(TemporalType.DATE)
        @Column(name = "DATEX", unique = true, nullable = false, length = 10)
        public Date getDate() {
            return this.date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

    }

当我尝试运行这个测试时:

    package com.mc;

    import java.util.Date;

    import org.hibernate.Session;

    import com.mc.stock.Stock;
    import com.mc.stock.StockDailyRecord;
    import com.mc.util.HibernateUtil;

    public class App {

        public static void main(String[] args) {
            System.out.println("Hibernate one to many (Annotation)");
            Session session = HibernateUtil.getSessionFactory().openSession();

            session.beginTransaction();

            Stock stock = new Stock();
            stock.setStockCode("7052");
            stock.setStockName("PADINI");
            session.save(stock);


            StockDailyRecord stockDailyRecords = new StockDailyRecord();
            stockDailyRecords.setPriceOpen(new Integer("2"));
            stockDailyRecords.setPriceClose(new Integer("11"));
            stockDailyRecords.setPriceChange(new Integer("10"));
            stockDailyRecords.setVolume(30L);
            stockDailyRecords.setDate(new Date());

            stockDailyRecords.setStock(stock);


            stock.getStockDailyRecords().add(stockDailyRecords);

            session.save(stockDailyRecords);

            session.getTransaction().commit();
            System.out.println("Done");
        }
    }

我得到这个错误:

2011-08-12_02:14:43.296 WARN  o.h.util.JDBCExceptionReporter 
    - SQL Error: 2291, SQLState: 23000
2011-08-12_02:14:43.296 ERROR o.h.util.JDBCExceptionReporter 
    - ORA-02291: integrity  constraint (HX.SYS_C004028) violated - parent key not found
2011-08-12_02:14:43.296 WARN  o.h.util.JDBCExceptionReporter 
    - SQL Error: 2291, SQLState: 23000
2011-08-12_02:14:43.296 ERROR o.h.util.JDBCExceptionReporter 
    - ORA-02291: integrity constraint (HX.SYS_C004028) violated - parent key not found

Exception in thread "main" org.hibernate.exception.ConstraintViolationException: 
    Could not execute JDBC batch update

我是 hibernate 新手,我会感谢任何帮助

提前致谢。

【问题讨论】:

    标签: java oracle hibernate orm hibernate-mapping


    【解决方案1】:

    您没有从库存 (setStockDailyRecords) 设置 Set 的内容。我会尝试将setStockDailyRecords 注释为

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock", inverse = "true")
    

    这意味着集合不是直接在数据库中创建的,他们使用反向关系检索它(通过 StockDailyRecord 中的 FK)


    已更新以回答 MHERO 的第一条评论。

    检查 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/collections.html#collections-mapping 的 inverse 属性。

    您拥有的其他选项是在会话关闭之前移动 save(stock)(请记住使用适当的值设置 setStockDailyRecords 集。

    【讨论】:

    • 抱歉,我无法在 javax.persistence.OneToMany 中找到“逆”
    【解决方案2】:

    所以HX.SYS_C004028 是 STOCK 和 STOCKDAILYRECORD 表之间的外键名称。这是一个强制执行业务规则的数据库约束,每个 STOCKDAILYRECORD 必须属于一个且只有一个 STOCK 记录。

    约束将 STOCKDAILYRECORD 上的列与 STOCK 表的主键链接。如果你有一个健全的数据模型,列将共享相同的名称,我希望它是 STOCKCODE 列。

    您可以通过查询数据字典来检查是否是这种情况:

    select column_name from all_cons_columns
    where owner = 'HX'
    and constraint_name = 'SYS_C004028'
    /
    

    (顺便说一句,系统生成的约束名称很糟糕:我们可以在创建约束时包含有意义的名称,这在尝试调查此类事情时非常有用。)

    您没有填充 STOCKCODE。所以也许 Hibernate 正在处理这个问题,而不是正确地处理它。例如,默认的 Hibernate 行为是在父记录之前插入子记录。有几种解决方法,但最好的方法是配置 Hibernate,以便在子外键列上强制执行单向一对多映射。这是通过设置not-null 属性来完成的:

    <set name="stockDailyRecord" lazy="true" cascade="all-delete-orphan">
        <key column="STOCK_CODE_FK" not-null=”true” update=”false”/>
        <one-to-many class="com.stock.dto.episode.StockDailyRecordDTO"/>
    </set>
    

    (您的命名约定会有所不同)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-24
      • 2020-01-14
      • 1970-01-01
      • 2021-12-13
      • 2017-10-01
      • 2019-04-12
      相关资源
      最近更新 更多