hibernate剔除时报identifier of an instance of xx was altered from xx to xx

hibernate删除时报identifier of an instance of xx was altered from xx to xx?org.hibernate.HibernateE

hibernate删除时报identifier of an instance of xx was altered from xx to xx

?org.hibernate.HibernateException: identifier of an instance of com.gwideal.apps.xjzeg.entity.rota.NightshiftTemporary was altered from 47392c5531464d5d97a4955c8e85a92b to fe21e9b9d5754adfaa5ada7982428cc7,47392c5531464d5d97a4955c8e85a92b

?

新泾镇公务员平台街镇版接入系统

?

大致过程:

1、页面参数是id=fe21e9b9d5754adfaa5ada7982427,47392c5531464d5d55c8e85a92b

2、action 是 implements ModelDriven<T>, Preparable的

prepare方法中对实体entity?进行了hibernate的查询操作,使之和hibernate的session关联起来

@Override

protected void prepareModel() throws Exception {

....

entity =nightShiftTemporaryManager.getNightShift(temId);

....

}

?

?3、在action中调用的方法中执行了删除操作

nightShiftTemporaryManager.deleteNightShift(removeId);其中removeId是对id的截取

然后报错,debug定位到?SimpleHibernateDao<T, PK extends Serializable>中的session.delete(entity);方法

?

4、action配置的是paramsPrepareParamsStack拦截栈,该栈中拦截器顺序如下

?

<interceptor-stack name="paramsPrepareParamsStack">                <interceptor-ref name="exception"/>                <interceptor-ref name="alias"/>                <interceptor-ref name="i18n"/>                <interceptor-ref name="checkbox"/>                <interceptor-ref name="multiselect"/>                <interceptor-ref name="params">                    <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>                </interceptor-ref>                <interceptor-ref name="servletConfig"/>                <interceptor-ref name="prepare"/>                <interceptor-ref name="chain"/>                <interceptor-ref name="modelDriven"/>                <interceptor-ref name="fileUpload"/>                <interceptor-ref name="staticParams"/>                <interceptor-ref name="actionMappingParams"/>                <interceptor-ref name="params">                    <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>                </interceptor-ref>                <interceptor-ref name="conversionError"/>                <interceptor-ref name="validation">                    <param name="excludeMethods">input,back,cancel,browse</param>                </interceptor-ref>                <interceptor-ref name="workflow">                    <param name="excludeMethods">input,back,cancel,browse</param>                </interceptor-ref>            </interceptor-stack>

?其中关键拦截器:

?

params : Sets the request parameters onto the Action

prepare :If the Action implements Preparable, calls its prepare method

modelDriven:If the Action implements ModelDriven, pushes the getModel Result onto the Value Stack

actionMappingParams:这是params?参数拦截器的子类

?

解释大概原因:

该action是实现ModelDriven的,则在modelDrivenInterceptor?拦截器中,? 把entity?放入了valueStatck 中的栈顶,在接下来的actionMappingParams拦截器又把id参数赋值给了valueStatck?中root对象的id属性,这里即entity?中的id属性。所以在执行action中方法的时候,entity?的id值被赋予了参数id的值fe21e9b9d5754adfaa5ada7982428cc7,47392c5531464d5d97a4955c8e85a92b,所以在调用session.delete(entity)中。hibernate检测到了持久对象entity?的id被改变,抛出了异常;

?

由关键拦截器顺序5hibernate剔除时报identifier of an instance of xx was altered from xx to xx个步骤解释具体原因:

?

?

step1、params : Sets the request parameters onto the Action

?在该拦截器中,stuts2对action中的id属性赋值fe21e9b9d5754adfaa5ada7982428cc7,47392c5531464d5d97a4955c8e85a92b

?

step2、prepare :If the Action implements Preparable, calls its?prepare?method

在该拦截器中,拦截器调用了action中prepare?方法,而该方法把实体entity 和hibenate的session产生了关联,使起变成了hibernate中的持久化对象

?

step3、modelDriven:If the Action implements ModelDriven, pushes the?getModel?Result onto the Value Stack

在该拦截器中,把action中的实体entity 放入Value Stack中,使其在接下来的参数拦截中接受参数

?

step4、actionMappingParams:这是params?参数拦截器的子类

把请求参数id,赋给entity?的id

?

step5、所以在接下来的执行action方法中,调用session.delete(entity)中。hibernate检测到了持久对象entity?的id被改变,抛出了异常

?

?

?

?

?