`

hibernate 一对多映射 问题解决

阅读更多
现有主表Report   从表reportUser 

<set name="reportUsers" cascade="all-delete-orphan" lazy="false"
inverse="false">
<key column="report_id_" />
<one-to-many class="ReportUser" />
</set>

看Report中的set配置

我的期望是由Report 即一的一端完全控制,那么可能会出现如下问题:
1.若 lazy="true" ,在执行set=report.getReportUser()是会出现no session错误,因此这里设为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它
会有 insert report_user_(...null,..)
然后才是 update  report set ....

update 或 delete:先setnull,然后update  delete
会有 update report_user_ set report_id_ =null where...

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

4. 对set的操作,不管是create,update,delete ,都需要从一的一方get
即report.getReportUser(),如果你new Set()给他,那么这个set将不被hibernate所管控,失去了控制, 会出现, you set is update by another  tranc  你的set被另一个事务更改

因此,在report中的set 声明时 需要初始化,防止,create的时候 getReportUser 为空。
private Set<ReportUser> reportUser=new HashSet<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会自动删除

更多关于cascade inverse 等属性的用法,参见http://www.cnblogs.com/amboyna/archive/2008/02/18/1072260.html
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics