2011-03-27 125 views
0

我使用hibernate作为ORM框架,这是我第一次用它来写操作。当使用struts2和休眠更新实体时得到NonUniqueObjectException

为了这个应用,我只是使用休眠从数据库读取数据。

在我的Struts动作,我尝试更新一个名为“任务”的实体,这是在更新页面的形式:

<s:form action="task_update" namespace="/common" cssStyle="width:95%"> 
    <s:textfield value="%{task.id}" cssStyle="display:none" name="task.id"></s:textfield> 
    <s:textfield name="task.name" value="%{task.name}" label="TaskName"/> 

    <s:select list="task.managers" 
     listKey="id" listValue="name" label="Manager" value="%{task.manage}" name="task.department.id"> 
    </s:select> 

    <s:select list="#session.current_user.departments" 
     listKey="id" listValue="name" label="Departmentn of this task" value="%{task.department.{id}}" name="task.department.id"> 
    </s:select> 
    <table> 
     <caption align="left">Steps</caption> 
     <tr> 
      <th>Name</th> 
      <th>End Time</th> 
      <th>Operators</th> 
      <th>Status</th> 
      <th>Set the order</th> 
      <th><span id="addStep" style="cursor:pointer" >Add Steps</span></th> 
     </tr> 
     <s:iterator value="task.steps"> 
      <tr class="step"> 
       <td> 
        <s:textfield name="task.steps[0].name" value="%{#this.name}" theme="simple"/> 
        <s:textfield name="task.steps[0].id" value="%{#this.id}" theme="simple" cssStyle="display:none"/> 
        <s:textfield name="task.steps[0].position" value="%{#this.position}" theme="simple" cssStyle="display:none" class="position"/> 
       </td> 
       <td><s:textfield name="task.steps[0].end" value="%{#this.end}" theme="simple"/></td> 
       <td>   
        <s:select list="allOpIndb" listKey="id" listValue="name" value="%{#this.operator.{id}}" 
         name="task.steps[0].operator.id" multiple="true" theme="simple" id="a"> 
        </s:select> 
       </td> 
       <td> 
        <s:select list="@[email protected]()" theme="simple" 
         name="task.steps[0].status" listValue="cnValue" value="%{#this.status}" id="b"/> 
       </td> 
       <td> 
        <span class="up">up</span> 
        <span class="down">down</span> 
        <span class="del">del</span> 
       </td> 
       <td></td> 
      </tr> 
     </s:iterator> 
     <tr> 
      <td colspan="6"> 
       <s:submit value="Submit"></s:submit> 
      </td> 
     </tr> 
    </table> 
</s:form> 

此页面的整个代码可以发现here

然后在struts2动作中,我得到由struts2创建的任务对象(以下示例中的“task”对象),并在db中找到正在更新的对象(以下示例中的“task_db”对象):

public String task_update{ 
    DozerBeanMapper dbm = new DozerBeanMapper(); 
    // the 'task' object is created by struts2 
    taskid = task.getId(); 
    String name_st = task.getName(); 
    int dep_id_st = task.getDepartment().getId(); 
    List<TaskStep> steps_st = task.getSteps(); 

    TaskDaoImpl tkDao = new TaskDaoImpl(); 
    TaskStepDaoImpl tsDao = new TaskStepDaoImpl(); 
    OperatorDaoImpl opDao = new OperatorDaoImpl(); 
    DepartmentDaoImpl depDao = new DepartmentDaoImpl(); 

    List<TaskStep> step_db = new ArrayList<TaskStep>(); 
    for (TaskStep step_st : steps_st) { 
     int tsid = step_st.getId(); 
     TaskStep ts_db = tsDao.queryStepById(tsid); 
     if (ts_db == null) { 
      ts_db = step_st; 
     } else 
      dbm.map(step_st, ts_db); 
     // sest the operators 
     List<Operator> ops_to_db = new ArrayList<Operator>(); 
     for (Operator op_st : step_st.getOperator()) { 
      ops_to_db.add(opDao.queryOperatorById(op_st.getId())); 
     } 
     ts_db.setOperator(ops_to_db); 
     step_db.add(ts_db); 
    } 
    //set the id of the task have the same id with task_db,so set its id to a unimpossible value 
    task.setId(-100); 
    //set it to null! 
    task=null; 
    Task task_db = tkDao.queryTaskById(taskid); 
    task_db.setName(name_st); 
    task_db.setDepartment(depDao.queryDepartById(dep_id_st)); 
    task_db.setSteps(step_db); 

    tkDao.updateTask(task_db); 
} 

当我提交表单时,我得到了“org.hibernate.NonUniqueObjectException:”: 具有相同标识符值的不同对象已与会话相关联:[com.infomanager.entity.Task#4]。

我想知道为什么?我已将任务的ID设置为-100,并将其设置为空。

什么问题?

以下是我的分贝tabls的realation船: enter image description here

而且整个项目可以在这里找到:https://github.com/hguser/TaskManager

回答

0

基本上,休眠的意思是,你有两个对象,其具有相同的标识符(相同的主键),但它们不是同一个对象。

关注此帖可能对你有帮助。 NonUniqueObjectException

只有当hibernate在会话上下文中找到具有相同标识符的两个对象时,这个异常才会出现。

+0

我知道什么冬眠说,我试图调试和发现错误,但我不能。在我的应用程序中更新的实体是嵌套的对象...( – hguser 2011-03-27 03:58:38