Нарушено ограничение целостности спящего режима - PullRequest
1 голос
/ 12 августа 2011

У меня проблема с отображением оракула от Hibernate

Я получил эти классы

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

Я новичок в спящем режиме и буду благодарен за любую помощь по этому вопросу

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 12 августа 2011

Вы не устанавливаете содержимое набора со склада (setStockDailyRecords). Я бы попробовал аннотировать setStockDailyRecords как

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

Это означает, что набор не создается непосредственно в базе данных, они извлекают его, используя обратную связь (через FK в StockDailyRecord)


ОБНОВЛЕНО, чтобы ответить на первый комментарий MHERO.

Проверьте http://docs.jboss.org/hibernate/core/3.3/reference/en/html/collections.html#collections-mapping для обратного атрибута.

Другой вариант, который у вас есть, это перемещать save (stock) непосредственно перед закрытием сессии (не забудьте установить Set of setStockDailyRecords с соответствующими значениями.

0 голосов
/ 12 августа 2011

Итак, 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'
/

(кстати, наличие системных сгенерированных имен ограничений - отстой: мы можем включать значимые имена при создании ограничений, что очень полезно при попытке исследовать подобные вещи.)

Вы не заполняетеСТОККОД.Так что, возможно, 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>

(ваши соглашения об именах могут отличаться)

...