违反了Hibernate oracle完整性约束

时间:2011-08-12 07:23:01

标签: java oracle hibernate orm hibernate-mapping

我在使用hibernate

映射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的新手,我会感谢任何帮助

提前致谢。

2 个答案:

答案 0 :(得分:2)

您没有设置库存设置(setStockDailyRecords)的内容。我会尝试将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的逆属性。

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

答案 1 :(得分:0)

因此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>

(您的命名惯例会有所不同)