【问题标题】:get NonUniqueObjectException when update entity using struts2 and hibernate使用 struts2 和休眠更新实体时获取 NonUniqueObjectException
【发布时间】:2011-03-27 01:49:11
【问题描述】:

我使用hibernate作为ORM框架,这是我第一次使用它进行编写操作。

在这个应用程序之前,我只是使用hibernate从数据库中读取数据。

在我的 struts 操作中,我尝试更新一个名为“Task”的实体,这是更新页面中的表单:

<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="@com.infomanager.entity.TaskStepStatus@values()"  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,并将其设置为 null。

有什么问题?

以下是我的数据库中表的实际情况:

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

【问题讨论】:

    标签: hibernate struts2


    【解决方案1】:

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

    关注这篇文章可能会对你有所帮助。 NonUniqueObjectException

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

    【讨论】:

    • 我知道hibernate在说什么,我已经尝试调试并找到错误,但我不能。我的应用中要更新的实体是嵌套对象...(
    猜你喜欢
    • 2011-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-24
    • 2019-06-22
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多