在组合条件中映射主表中的List时如果使用以下配置方式,注意inverse部分为true,其它如cascade或为all也可,只是我这种可以在details.remove()时也会删除.这种策略更方便一些.
<list name="details" cascade="all-delete-orphan" inverse="true" lazy="false">
<key column="PlanID"></key>
<index column="Orders"></index>
<one-to-many class="package.PlanDetail"/>
</list>
如果inverse="false"则可以成功更新Orders的索引值.如果是true,需要手动维护,如果没有手动维护则会出现保存时空值,删除/更新时出错的情况.这时需要手动维护,怎么维护呢?
我是将Orders列作为主从类中从类的属性,<property name="ord" column="Orders"/>,并生成getter/setter,然后在保存主对象时取出所有从对象,一一设置其值.类似的xml如:
<property name="ord" type="java.lang.Integer">
<column name="Orders" />
</property>
代码类似于:
if (details != null && details.size() > 0) {
int i=0;
for (PlanDetail detail : details) {
detail.setOrd(i++);
detail.setPlanMaster(master);
}
return (Long) save(master);
}
注意:如果使用以上代码int i=1开始,因为索引从1开始,故需要将<index/>改为 <list-index base="1">,这样就能正确识别Details,如果没有,则Hibernate会按0开始计算Details中1前面会有空的实体,而size()也会多出一个.base只是告诉从什么开始,在List的相关操作索引还是从0开始,比如:remove(0).所以在index中对应的
index remove(0) 删除后List.size()=2, list-index base="1" remove(0)之后同前,
第一个为空,第二个为index_column为1的记录 size()依然=2
index_column get索引 index_column index_column get索引
0 0 1 0
1 1 1 2 1
如果想在删除Details的某项后自动更新索引值,还是把inverse设为false吧,虽然这样会发送多一点sql语句.真是想方便就要牺牲点性能,想性能就得自己整.