Hibernate - Каскадный пример (сохранение, обновление, удаление и удаление-сирота)

Hibernate - Каскадный пример (сохранение, обновление, удаление и удаление-сирота)

Каскад - это удобная функция для сохранения строк кода, необходимых для ручного управления состоянием другой стороны.

Ключевое слово «Каскад» часто появляется в отображении коллекции, чтобы автоматически управлять состоянием коллекции. В этом руководстве этотone-to-many example будет использоваться для демонстрации каскадного эффекта.

Каскадный пример сохранения / обновления

В этом примере, если «Stock» сохранен, все его ссылки «stockDailyRecords» также должны быть сохранены в базе данных.

1. Нет каскада сохранения-обновления

Вprevious section, если вы хотите сохранить «Stock» и связанный с ним «StockDailyRecord» в базе данных, вам необходимо сохранить их по отдельности.

Stock stock = new Stock();
StockDailyRecord stockDailyRecords = new StockDailyRecord();
//set the stock and stockDailyRecords  data

stockDailyRecords.setStock(stock);
stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stock);
session.save(stockDailyRecords);

Выход

Hibernate:
    insert into example.stock (STOCK_CODE, STOCK_NAME)
    values (?, ?)

Hibernate:
    insert into example.stock_daily_record
    (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values (?, ?, ?, ?, ?, ?)

2. С каскадом сохранения-обновления

cascade=”save-update” объявлен в «stockDailyRecords», чтобы включить каскадный эффект сохранения-обновления.



      
            
      
      
Stock stock = new Stock();
StockDailyRecord stockDailyRecords = new StockDailyRecord();
//set the stock and stockDailyRecords  data

stockDailyRecords.setStock(stock);
stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stock);

Выход

Hibernate:
    insert into example.stock (STOCK_CODE, STOCK_NAME)
    values (?, ?)

Hibernate:
    insert into example.stock_daily_record
    (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values (?, ?, ?, ?, ?, ?)

Кодsession.save(stockDailyRecords); больше не требуется, когда вы сохраняете «Stock», он будет «каскадировать» операцию сохранения на «stockDailyRecords», на который он ссылается, и автоматически сохранит их в базе данных.

Пример каскадного удаления

В этом примере, если «Stock» удален, все его ссылки «stockDailyRecords» также должны быть удалены из базы данных.

1. Каскад без удаления

Вы должны зациклить все «stockDailyRecords» и удалить его один за другим.

Query q = session.createQuery("from Stock where stockCode = :stockCode ");
q.setParameter("stockCode", "4715");
Stock stock = (Stock)q.list().get(0);

for (StockDailyRecord sdr : stock.getStockDailyRecords()){
         session.delete(sdr);
}
 session.delete(stock);

Выход

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

2. С каскадом удаления

cascade=”delete” объявлен в «stockDailyRecords», чтобы включить каскадный эффект удаления. При удалении «Stock» все его ссылки «stockDailyRecords» будут удалены автоматически.



      
            
      
      
Query q = session.createQuery("from Stock where stockCode = :stockCode ");
q.setParameter("stockCode", "4715");
Stock stock = (Stock)q.list().get(0);
session.delete(stock);

Выход

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

Каскадный пример удаления-сироты

В вышеупомянутой опции каскадного удаления, если вы удаляете Stock, все его упомянутые «stockDailyRecords» также будут удалены из базы данных. Как насчет того, если вы просто хотите удалить две ссылочные записи «stockDailyRecords»? Это называется удаление сирот, см. Пример ...

1. Без удаления-сиротский каскад

Вам нужно удалить «stockDailyRecords» по одному.

StockDailyRecord sdr1 = (StockDailyRecord)session.get(StockDailyRecord.class,
                                            new Integer(56));
StockDailyRecord sdr2 = (StockDailyRecord)session.get(StockDailyRecord.class,
                                            new Integer(57));

session.delete(sdr1);
session.delete(sdr2);

Выход

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?
Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

2. С каскадом удаления сирот

cascade=”delete-orphan” объявлен в «stockDailyRecords», чтобы включить каскадный эффект удаления сирот. Когда вы сохраняете или обновляете Stock, он удаляет те «stockDailyRecords», которые уже помечены как удаленные.



      
            
      
      
StockDailyRecord sdr1 = (StockDailyRecord)session.get(StockDailyRecord.class,
                                       new Integer(56));
StockDailyRecord sdr2 = (StockDailyRecord)session.get(StockDailyRecord.class,
                                       new Integer(57));

Stock stock = (Stock)session.get(Stock.class, new Integer(2));
stock.getStockDailyRecords().remove(sdr1);
stock.getStockDailyRecords().remove(sdr2);

session.saveOrUpdate(stock);

Выход

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?
Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Короче говоря, delete-orphan позволяет родительской таблице удалять несколько записей (delete orphan) в своей дочерней таблице.

Как включить каскад?

Каскад поддерживается как в XML-файле отображения, так и в аннотации.

1. XML-файл отображения

В файле сопоставления XML объявлено ключевое словоcascade в переменной отношения.



      
            
      
      

2. аннотирование

В аннотации объявленыCascadeType.SAVE_UPDATE (сохранение, обновление) иCascadeType.REMOVE (удаление) в аннотации @Cascade.

        //Stock.java
        @OneToMany(mappedBy = "stock")
        @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
    public Set getStockDailyRecords() {
        return this.stockDailyRecords;
    }

Дальнейшее изучение -Cascade – JPA & Hibernate annotation common mistake.

обратный каскад против

Оба понятия совершенно разные, см.differential here.

Заключение

Каскад - очень удобная функция для автоматического управления состоянием другой стороны. Однако эта функция имеет свою цену, если вы не используете ее с умом (обновлять или удалять), она будет генерировать много ненужных каскадных эффектов (каскадное обновление), чтобы замедлить вашу производительность, или удалить (каскадное удаление) некоторые данные, которые вы не делали ожидается.