Hibernate Set Cascade Example (save, update, delete and delete-orphan)
来源:互联网 发布:德国巧克力价格 知乎 编辑:程序博客网 时间:2024/05/16 19:48
Cascade is a convenient feature to save the lines of code needed to manage the state of the other side manually.
The “Cascade” keyword is often appear on the collection mapping to manage the state of the collection automatically. In this tutorials, this one-to-many example will be used to demonstrate the cascade effect.
Cascade save / update example
In this example, if a ‘Stock’ is saved, all its referenced ‘stockDailyRecords’ should be saved into database as well.
1 - No save-update cascade
In previous section, if you want to save the ‘Stock’ and its referenced ‘StockDailyRecord’ into database, you need to save both individually.
Stock stock = new Stock();StockDailyRecord stockDailyRecords = new StockDailyRecord();//set the stock and stockDailyRecords datastockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords);session.save(stock);session.save(stockDailyRecords);//运行结果Hibernate: insert into mkyong.stock (STOCK_CODE, STOCK_NAME) values (?, ?)Hibernate: insert into mkyong.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
2 - With save-update cascade
The cascade=”save-update” is declared in ‘stockDailyRecords’ to enable the save-update cascade effect.
<!-- Stock.hbm.xml --><set name="stockDailyRecords" cascade="save-update" table="stock_daily_record"...> <key> <column name="STOCK_ID" not-null="true" /> </key> <one-to-many class="com.mkyong.common.StockDailyRecord" /> </set>
Stock stock = new Stock();StockDailyRecord stockDailyRecords = new StockDailyRecord();//set the stock and stockDailyRecords datastockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock);//运行结果Hibernate: insert into mkyong.stock (STOCK_CODE, STOCK_NAME) values (?, ?)Hibernate: insert into mkyong.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
The code session.save(stockDailyRecords); is no longer required, when you save the ‘Stock’, it will “cascade” the save operation to it’s referenced ‘stockDailyRecords’ and save both into database automatically.
Cascade delete example
In this example, if a ‘Stock’ is deleted, all its referenced ‘stockDailyRecords’ should be deleted from database as well.
1 - No delete cascade
You need to loop all the ‘stockDailyRecords’ and delete it one by one.
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 mkyong.stock_daily_record where DAILY_RECORD_ID=?Hibernate: delete from mkyong.stock where STOCK_ID=?
2 - With delete cascade
The cascade=”delete” is declared in ‘stockDailyRecords’ to enable the delete cascade effect. When you delete the ‘Stock’, all its reference ‘stockDailyRecords’ will be deleted automatically.
<!-- Stock.hbm.xml --><set name="stockDailyRecords" cascade="delete" table="stock_daily_record" ...> <key> <column name="STOCK_ID" not-null="true" /> </key> <one-to-many class="com.mkyong.common.StockDailyRecord" /></set>
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 mkyong.stock_daily_record where DAILY_RECORD_ID=?Hibernate: delete from mkyong.stock where STOCK_ID=?
Cascade delete-orphan example
In above cascade delete option, if you delete a Stock , all its referenced ‘stockDailyRecords’ will be deleted from database as well. How about if you just want to delete two referenced ‘stockDailyRecords’ records? This is called orphan delete, see example…
1 - No delete-orphan cascade
You need to delete the ‘stockDailyRecords’ one by one.
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 mkyong.stock_daily_record where DAILY_RECORD_ID=?Hibernate: delete from mkyong.stock_daily_record where DAILY_RECORD_ID=?
2 - With delete-orphan cascade
The cascade=”delete-orphan” is declared in ‘stockDailyRecords’ to enable the delete orphan cascade effect. When you save or update the Stock, it will remove those ‘stockDailyRecords’ which already mark as removed.
<!-- Stock.hbm.xml --><set name="stockDailyRecords" cascade="delete-orphan" table="stock_daily_record" > <key> <column name="STOCK_ID" not-null="true" /> </key> <one-to-many class="com.mkyong.common.StockDailyRecord" /></set>
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 mkyong.stock_daily_record where DAILY_RECORD_ID=?Hibernate: delete from mkyong.stock_daily_record where DAILY_RECORD_ID=?
In short, delete-orphan allow parent table to delete few records (delete orphan) in its child table.
How to enable cascade ?
The cascade is supported in both XML mapping file and annotation.
1 - XML mapping file
In XML mapping file, declared the cascade keyword in your relationship variable.
<!-- Stock.hbm.xml --><set name="stockDailyRecords" cascade="save-update, delete" table="stock_daily_record" ...> <key> <column name="STOCK_ID" not-null="true" /> </key> <one-to-many class="com.mkyong.common.StockDailyRecord" /></set>
2 - Annotation
In annotation, declared the CascadeType.SAVE_UPDATE (save, update) and CascadeType.REMOVE (delete) in @Cascade annotation.
Java//Stock.java @OneToMany(mappedBy = "stock") @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE}) public Set<StockDailyRecord> getStockDailyRecords() { return this.stockDailyRecords; }
Further study – Cascade – JPA & Hibernate annotation common mistake.
inverse vs cascade
Both are totally different notions, see the differential here.
Conclusion
Cascade is a very convenient feature to manage the state of the other side automatically. However this feature come with a price, if you do not use it wisely (update or delete), it will generate many unnecessary cascade effects (cascade update) to slow down your performance, or delete (cascade delete) some data you didn’t expected.
- Hibernate Set Cascade Example (save, update, delete and delete-orphan)
- hibernate cascade属性 all-delete-orphan
- hibernate cascade属性 all-delete-orphan
- hibernate cascade属性 all-delete-orphan
- HIbernate级联删除(hibernate 双向一对多中 主表设置cascade="all-delete-orphan",在save时出现
- Hibernate中cascade为all-delete-orphan使用情况补充
- Hibernate all-delete-orphan
- cascade="all-delete-orphan" 处理
- cascade="all-delete-orphan" 处理
- hibernate的save、update、delete原理
- Hibernate中cascade为all-delete-orphan与all的区别
- hibernate cascade="all-delete-orphan"(所有-删除-孤儿)释疑
- 晕,hibernate 的 merge和cascade="all-delete-orphan"要慎重合在一起使用
- on delete set null & on delete cascade
- on delete set null & on delete cascade
- ON DELETE CASCADE ON UPDATE CASCADE
- ON UPDATE CASCADE ON DELETE CASCADE
- hibernate的saveorUpdate与unsaved-value,save,update,delete总结
- centos服务器配置caffe环境
- Unity计时器设计 - 基础计时器
- react native 嵌入原生Android应用中的问题
- [生存志] 第119节 刘安编著淮南鸿烈
- angularjs 自定义指令的分类
- Hibernate Set Cascade Example (save, update, delete and delete-orphan)
- MSP430 12864显示
- 如何配置spring+springmvc+mybatis环境
- 监视Linux服务器的性能
- v-model和v-for指令
- java客户端操作Hbase
- 微信开发,本地地址映射到外网的方法
- 函数的可重入性理解
- 实现家庭WiFi网络全覆盖