精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-08-15
songxh2 写道 janh 写道 修改对象应该在持久化对象的基础上进行修改。
根据id,get获取到对应的持久化对象,再设置要改变的属性值。 关联对象也同样,根据父id,get获取到anotherParent,再child.setParent(anotherParent); 谢谢!说的有理,建议加50分。 但是还是发现问题依然存在!!!!! 我如你所说添加了如下修改方式代码,(其实我原来也做过这个测试,只是不很确定..) public String update() { try { //得到新的Id及其持久化对象p,并重新设置child的parent Integer pid=child.getParent().getId(); Parent p=childDAO.getParentById(pid); child.setParent(p); childDAO.update(child);//此步依然出现错误!!!! return "success"; } catch (RuntimeException e) { return "success"; } } 错误原因还是: org.hibernate.HibernateException: identifier of an instance of test.Parent was altered from 1 to 2 不得其解,难道不是不能修改二级对象的id,而是其他原因?比如单向many-to-one关联不能更新关联关系? |
|
返回顶楼 | |
发表时间:2007-08-15
好像你的parent对象一直在session的管理之下,是一个持久化对象,而并非如你所说的 “只对parent的id属性设置了值,其他值都为空”的一个临时对象,这样虽然没有对parent对象做更新操作,但是当事务提交时,hibernate会自动把对持久化对象的修改保存到数据库中,检查发现id发生了改变,所以报错。
你的对象为什么一直在session的管理之下呢,是每次request到来时提前准备好的还是每次session都不关? |
|
返回顶楼 | |
发表时间:2007-08-15
引用 好像你的parent对象一直在session的管理之下,是一个持久化对象,而并非如你所说的 “只对parent的id属性设置了值,其他值都为空”的一个临时对象,这样虽然没有对parent对象做更新操作,但是当事务提交时,hibernate会自动把对持久化对象的修改保存到数据库中,检查发现id发生了改变,所以报错。
你的对象为什么一直在session的管理之下呢,是每次request到来时提前准备好的还是每次session都不关? 我用了 在web.xml中用了Spring 的 opensessionviewFilter过滤器的,在web应用的时候是打开的。 <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> |
|
返回顶楼 | |
发表时间:2007-08-16
问题基本解决,问题在于jsf的backingbean对象更新机制。。。需要用如下方法避免。
/* 用户提交页面时,backing bean 的getChild()方法应该提供一个临时对象让jsf来组装更新数据比较合适, * 因为jsf恢复数据时首先会用这个方法取个原始对象,然后在这个对象的基础上组装新的数据。 * 注意一定先提供一个临时对象而非持久化对象,因为在组装数据时,会用新数据替换旧数据, * 如果被替换的是持久化对象及其子对象的Id值时(比如child.parent.id),其实你可能只是是想替换与parent的关系, * 但jsf系统并不知道你是想要建立新的关系,所以会抛出子对象的Id被强制修改的错误!而持久化对象的Id值是不能被更改的。 * backing bean 的getChild()方法必须在用户提交页面时应该提供一个临时对象,jsf恢复数据会用这个方法取原始对象,注意一定先提供一个临时对象而非持久化对象, * 因为在组装数据时,会用新数据替换旧数据,如果被替换的是持久化对象,在替换子对象关系时,会检查到子对象的Id被强制修改的错误! */ public Child getChild() { if(child==null){ //child=(Child)childDAO.getChild(new Integer(4));不能直接实例化session对像,不然jsf会强制更新这个持久化对象的任何值,碰到many-to-one的关系更新,它也会认为是修改原来的持久化对象(应该是替换不是修改),而在修改id值时会抛出错误,无法保存数据。 child=new Child(); //临时对象 } return child; } |
|
返回顶楼 | |