我有如下的一对多关系 -
家长hbm: -
<hibernate-mapping>
<class name="ParentClass" table="PARENT_TABLE" schema="schemaname" lazy="false">
<cache usage="read-write" />
<id name="id" column="PARENT_ID_ID" type="java.lang.Long">
<generator class="sequence">
<param name="sequence">schemaname.parent_sequence_name</param>
</generator>
</id>
<version name="versionNumber" column="version_num" type="java.lang.Long" insert="false" />
<property name="recordStatus" column="RECORD_STATUS" type="java.lang.String" insert="false" />
<list name="children" cascade="all-delete-orphan">
<key column="PARENT_ID" />
<list-index column="LINE_NUMBER" />
<one-to-many class="ChildClass" />
</list>
&audit;
</class>
</hibernate-mapping>
Child hbm: -
<hibernate-mapping>
<class name="ChildClass" table="CHILD_TABLE" schema="schemaname" lazy="false">
<id name="id" column="CHILD_ID" type="java.lang.Long">
<generator class="native">
<param name="sequence">schema.child_sequence_name</param>
</generator>
</id>
<version name="versionNumber" column="VERSION_NUMBER" type="java.lang.Long" />
<property name="recordStatus" column="RECORD_STATUS" type="java.lang.String" />
<property name="lineNumber" column="LINE_NUMBER" type="java.lang.Long" />
<many-to-one name="parent" column="PARENT_ID" class="ParentClass" fetch="select" />
&audit;
</class>
</hibernate-mapping>
我正在以表格形式输入父级和子级,并使用Struts进入操作类。 action类执行.saveOrUpdate(parent)。
sessionFactory.getCurrentSession().saveOrUpdate(parent);
当我插入新的父级时,它会将子级插入正常。插入后,我将控件移回具有相同值的表单。然后,我更改了一个孩子的一些值并再次提交。在这种情况下,我可以看到(来自hibernate日志)父更新,但更新后的子进程未更新。
Hibernate中是否有一个选项可以在更新父级时强制更改的子级更新?如果只有更改后的孩子无法更新,我很乐意让所有孩子都得到更新。
如果此信息不足以理解我要做的事情,请告诉我,我会提供更多信息。
提前致谢
更新: -
我刚刚注意到Hibernate在尝试更新时会在子记录上抛出此异常: -
Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.efleets.services.billing.domain.InvoiceBulk#206]
at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1761)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2403)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2303)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2603)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at com.efleets.services.common.integration.GenericDAOImpl.flush(GenericDAOImpl.java:115)
感谢。任何帮助将不胜感激。
答案 0 :(得分:2)
您的映射看起来是正确的。如果从Child.hbm中删除version
子句,您的程序可能会有效,但这不是解决方案,因为您的应用程序不再正确。
你得到的例外可以很容易地用这个逻辑重现:
会话1加载行。
会话2加载行。
会话1修改行的任何列并保存它
会话2修改行并尝试保存它。现在出现异常。
在像您的情况一样的Web环境中,这通常不是错误。当两个用户同时修改相同数据时会发生这种情况。您必须捕获异常并向第二个用户发送有用的消息。
在您的情况下,代码中的任何位置都可能出现错误,在您发布的部分中不可见
请检查:
插入和更新,它们是在同一个会话中还是在两个不同的会话中?
如果一个会话,它是否会发生,那么不同会话会对孩子进行更新?
如果是两个会话,您是否使用相同或不同的子(!)对象实例?
你能做什么:
- 不要在两个不同的会话中使用任何Hibernate数据库对象的相同实例
- 在修改前,evict()
和load()
或refresh()
(Session
的所有方法),父母,也可能是孩子。
答案 1 :(得分:0)
您是否尝试过cascade="all"
而不是cascade="all-delete-orphan"
检查
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/example-parentchild.html