получить NonUniqueObjectException при обновлении сущности с использованием struts2 и hibernate - PullRequest
0 голосов
/ 27 марта 2011

Я использую hibernate в качестве фреймворка ORM, и я впервые использую его для операций записи.

Для этого приложения я просто использую hibernate для чтения данных из БД.

В своем действии 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="@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>

Полные коды этой страницы можно найти здесь :

Затем в действии struts2 я получаю объект задачи, созданный struts2 (объект «задача» в следующем примере), и нахожу обновляемый объект в базе данных (объект «задача_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].

Интересно, почему?Я установил идентификатор задачи равным -100, и установил его на ноль.

В чем проблема?

Ниже приведено описание корабля таблиц в моей БД: enter image description here

А весь проект можно найти здесь: https://github.com/hguser/TaskManager

1 Ответ

0 голосов
/ 27 марта 2011

По сути, hibernate говорит о том, что у вас есть два объекта, которые имеют одинаковый идентификатор (один и тот же первичный ключ), но они не являются одним и тем же объектом.

Следуйте этому посту, может быть, он вам поможет. NonUniqueObjectException

Это исключение существует только в том случае, если в спящем режиме обнаруживаются два объекта в контексте сеанса с одинаковым идентификатором.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...