Hibernate的merge问题

来源:互联网 发布:winhex写数据 编辑:程序博客网 时间:2024/06/06 00:22

一个问题,使用merge保存pojo失败;

有一个 Book 类,里面有若干属性和一个 ManyToOne 属性 Author;

首先new了一个Book对象,把变更的属性set进去,然后调用merge,打印sql发现没有update语句;

初步猜测可能是 new 出来的 Book 属于自由态导致Hibernate不会更新,估计不应该 new 出来,应该用Hibernate load 出来,但是也没有看到insert呀~

跟踪到源码,看到 DefaultMergeEventListener 中有一段注释,声称 new 出来的 pojo 在设置了 id 后也是会当做游离态处理的;所以不是这个问题;

继续跟踪源码到提交事务时,发现 DefaultFlushEventListener 在 performExecutions 中含有 updates 的 ActionQueue,且去执行了,则说明更新的动作已经生成了;

距离真相越来越近,已经快生成SQL了;

一路跟着源码到 AbstractEntityPersister 的 update,发现因为 tableUpdateNeeded 中属性为 false ,导致 updateOrInsert 没有调用,SQL没有执行;看了就是这个tableUpdateNeeded导致的了;

又是一番debugger,终于发现是因为 EntityUpdateAction 中存在 dirtyField 导致的;而这个 dirtyField 就是 Book 里的 Author 属性;

神奇的bug啊;

看来是因为 new 出来的 Book 里,author 属性为空,而Hibernate在将之与数据库快照比对时发现 author 不应为空,认为是脏字段,从而不保存 Book;

OK,改一下代码,new Book 后再把 Author 也 set 进去,执行 merge,果然有 sql 打印了!

所以:使用 merge 时,实体类如果没有关联,可以直接 new 出来,若是有关联,还是要先 load 一下;

原创粉丝点击