在休眠状态下,“ class”及其相关集合中的“ mutable ”默认为“ true”,这意味着该类或集合可以添加,更新和删除。 另一方面,如果将可变变量更改为false,则它在类及其相关集合中具有不同的含义。 让我们举一些例子来进一步了解它。
休眠一对多示例
我将以这个多对多的示例进行可变演示。 在此映射文件中,一个Stock属于许多StockDailyRecord。
<!-- Stock.hbm.xml -->
...
<hibernate-mapping>
<class name="com.mkyong.common.Stock" table="stock" >
<set name="stockDailyRecords" mutable="false" cascade="all"
inverse="true" lazy="true" table="stock_daily_record">
<key>
<column name="STOCK_ID" not-null="true" />
</key>
<one-to-many class="com.mkyong.common.StockDailyRecord" />
</set>
</class>
...
</hibernate-mapping>
如何声明可变?
XML映射文件和注释中都支持“可变”。
1. XML映射文件
在映射文件中,“ mutable ”关键字用于实现可变功能。
<!-- Stock.hbm.xml -->
...
<hibernate-mapping>
<class name="com.mkyong.common.Stock" table="stock" mutable="false" >
<set name="stockDailyRecords" mutable="false" cascade="all"
inverse="true" lazy="true" table="stock_daily_record" >
<key>
<column name="STOCK_ID" not-null="true" />
</key>
<one-to-many class="com.mkyong.common.StockDailyRecord" />
</set>
</class>
...
</hibernate-mapping>
2.注释
在注释中,关键字更改为@Immutable(mutable ='false')。
...
@Entity
@Immutable
@Table(name = "stock", catalog = "mkyong")
public class Stock implements java.io.Serializable {
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "stock")
@Immutable
public Set<StockDailyRecord> getStockDailyRecords() {
return this.stockDailyRecords;
}
...
课堂上可变
如果在类元素中声明了mutable =“ false”或@Immutable,则意味着对该类的更新将被忽略,但不会引发任何异常,仅允许添加和删除操作 。
1.测试插页
Stock stock = new Stock();
stock.setStockCode("7277");
stock.setStockName("DIALOG");
session.save(stock);
如果mutable =“ true”(默认值)或在类中未声明@Immutable。
输出量
Hibernate:
insert into mkyong.stock (STOCK_CODE, STOCK_NAME)
values (?, ?)
如果在类中声明了mutable =“ false”或@Immutable。
输出量
Hibernate:
insert into mkyong.stock (STOCK_CODE, STOCK_NAME)
values (?, ?)
类中的变量在“插入”操作中无效。
2.测试更新
Stock stock = (Stock)session.createQuery(
" from Stock where stockCode = '7277'").list().get(0);
stock.setStockName("DIALOG123");
session.saveOrUpdate(stock);
如果mutable =“ true”或没有在类中声明@Immutable。
输出量
Hibernate:
select ...from mkyong.stock stock0_
where stock0_.STOCK_CODE='7277'
Hibernate:
update mkyong.stock
set STOCK_CODE=?,STOCK_NAME=?
where STOCK_ID=?
如果在类中声明了mutable =“ false”或@Immutable。
输出量
Hibernate:
select ...from mkyong.stock stock0_
where stock0_.STOCK_CODE='7277'
类中的可变项不允许应用程序对其进行更新,'update'操作将被忽略并且不会引发异常
3.测试删除
Stock stock = (Stock)session.createQuery(
" from Stock where stockCode = '7277'").list().get(0);
session.delete(stock);
如果mutable =“ true”(默认值)或在类中未声明@Immutable。
输出量
Hibernate:
delete from mkyong.stock
where STOCK_ID=?
如果在类中声明了mutable =“ false”或@Immutable。
输出量
Hibernate:
delete from mkyong.stock
where STOCK_ID=?
类中的可变项在“删除”操作中无效。
集合可变
如果在集合中声明了mutable =“ false”或@Immutable,则表示该集合中不允许添加和删除孤儿,并且抛出异常,仅允许update和'cascade delete all' 。
1.测试插页
假设已启用级联插入。
Stock stock = (Stock)session.createQuery(
" from Stock where stockCode = '7277'").list().get(0);
StockDailyRecord sdr = new StockDailyRecord();
sdr.setDate(new Date());
sdr.setStock(stock);
stock.getStockDailyRecords().add(sdr);
session.save(stock);
如果mutable =“ true”(默认值)或在集合中未声明@Immutable。
输出量
Hibernate:
insert into mkyong.stock_daily_record
(STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
values (?, ?, ?, ?, ?, ?)
如果在集合中声明了mutable =“ false”或@Immutable。
输出量
Exception in thread "main" org.hibernate.HibernateException:
changed an immutable collection instance:
[com.mkyong.common.Stock.stockDailyRecords#111]
集合中的变量不允许进行“添加”操作,否则将引发异常。
2.测试更新
假设已启用级联更新。
Stock stock = (Stock)session.createQuery(
" from Stock where stockCode = '7277'").list().get(0);
StockDailyRecord sdr = stock.getStockDailyRecords().iterator().next();
sdr.setPriceChange(new Float(1.30));
session.saveOrUpdate(stock);
如果mutable =“ true”(默认值)或在集合中未声明@Immutable。
输出量
Hibernate:
update mkyong.stock_daily_record
set PRICE_CHANGE=?, ...
where DAILY_RECORD_ID=?
如果在集合中声明了mutable =“ false”或@Immutable。
输出量
Hibernate:
update mkyong.stock_daily_record
set PRICE_CHANGE=?, ...
where DAILY_RECORD_ID=?
集合中的变量在“更新”操作中无效。
3.测试delete-orphan
假定已启用级联删除孤儿 。
Stock stock = (Stock)session.createQuery(
" from Stock where stockCode = '7277'").list().get(0);
StockDailyRecord sdr = stock.getStockDailyRecords().iterator().next();
stock.getStockDailyRecords().remove(sdr);
session.saveOrUpdate(stock);
如果mutable =“ true”(默认值)或在集合中未声明@Immutable。
输出量
Hibernate:
delete from mkyong.stock_daily_record
where DAILY_RECORD_ID=?
如果在集合中声明了mutable =“ false”或@Immutable。
输出量
Exception in thread "main" org.hibernate.HibernateException:
changed an immutable collection instance:
[com.mkyong.common.Stock.stockDailyRecords#111]
集合中的变量不允许执行'delete-orphan'操作,否则将引发异常。
4.测试删除
假设已启用级联删除。
Stock stock = (Stock)session.createQuery(
" from Stock where stockCode = '7277'").list().get(0);
session.saveOrUpdate(stock);
如果mutable =“ true”(默认值)或在集合中未声明@Immutable。
输出量
Hibernate:
delete from mkyong.stock_daily_record
where DAILY_RECORD_ID=?
Hibernate:
delete from mkyong.stock
where STOCK_ID=?
如果在集合中声明了mutable =“ false”或@Immutable。
输出量
Hibernate:
delete from mkyong.stock_daily_record
where DAILY_RECORD_ID=?
Hibernate:
delete from mkyong.stock
where STOCK_ID=?
集合中的可变项在“删除”操作中无效,如果删除了父项,则其所有子项也将被删除,即使它是可变的。
为什么易变?
Mutable可以避免许多意外的数据库操作,例如添加,更新或删除一些不应该的记录。 此外,根据Hibernate文档,可变对象确实有一些次要的性能优化,始终建议您分析映射关系并根据需要实现可变对象。
摘要
1. mutable =“ false”或@Immutable在类中声明
这意味着将忽略此类的更新,但不会引发任何异常,仅允许添加和删除操作。
在具有mutable =” false”的类中– insert = allow,delete = allow,update =不允许
2.在集合中声明了mutable =“ false”或@Immutable
这意味着该集合中不允许添加和删除孤立对象,并且抛出异常时仅允许更新。 但是,如果启用了级联删除,则删除父级时,它的所有子级也会被删除,即使它是可变的。
在具有mutable =” false”的Collection中–插入=不允许,delete-orphan =不允许,delete = allow,update = allow
完全不变?
一个类可以完全不改变任何动作吗? 是的,在所有关系中都添加一个mutable =“ false”(插入=不允许,delete-orphan =不允许),对您要不可变的类添加mutable =“ false”(更新=不允许)。 现在,您有了一个完全不可变的类,但是,如果启用了层叠删除选项,那么当删除不可变类的父级时,您的不可变类也会被删除。
参考
1. http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/
翻译自: https://mkyong.com/hibernate/hibernate-mutable-example-class-and-collection/