hibernate 一对多映射 问题解决

现有主表Report从表reportUser

<setname="reportUsers"cascade="all-delete-orphan"lazy="false"

inverse="false">

<keycolumn="report_id_"/>

<one-to-manyclass="ReportUser"/>

</set>

看Report中的set配置

我的期望是由Report即一的一端完全控制,那么可能会出现如下问题:

1.若lazy="true",在执行set=report.getReportUser()是会出现nosession错误,因此这里设为lazy="false"

2.若cascade设为“save-update”或其他,那么你会发现,删除Report时,并没有把reportUser删除,只是把reportUser的report_id_字段设为了null

3.若1,2没问题,如果你的数据库中report_user_表的关联字段report_id_设为not-null,

则,更新或删除set的时候,会报不能为null的错误。

这是因为hibernate执行update,create,delete都分为2步,先插入null,或设为null,再update,

可以把hql打出来看

create:先插入null,然后update它

会有insertreport_user_(...null,..)

然后才是updatereportset....

update或delete:先setnull,然后updatedelete

会有updatereport_user_setreport_id_=nullwhere...

因此从表中的关联字段report_id_需要设为可以为空NULL

4.对set的操作,不管是create,update,delete,都需要从一的一方get

即report.getReportUser(),如果你newSet()给他,那么这个set将不被hibernate所管控,失去了控制,会出现,yousetisupdatebyanothertranc你的set被另一个事务更改

因此,在report中的set声明时需要初始化,防止,create的时候getReportUser为空。

privateSet<ReportUser>reportUser=newHashSet<ReportUser>();

5.操作示例

create:

set=report.getReportUser();

set.add(reportUser1);

set.add(reportUser2);

session...update(report);

reportUser1,2中不必要设置report或是reportId了,因为,此set已经是从report取出来的,会自动关联

update:

set=report.getReportUser();

set.clear();//先clear

set.add(reportUser1);

set.add(reportUser2);

session...update(report);

delete:

session...delete(report);

直接删除reort即可,reportUser会自动删除

更多关于cascadeinverse等属性的用法,参见http://www.cnblogs.com/amboyna/archive/2008/02/18/1072260.html

相关推荐