Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > different object with the same identifier value...


Автор: Fedrus 6.11.2007, 12:21
Здравствуйте все!
Есть форма на которую выводится список юзеров.
При нажатии на кнопку едит (возле соответствующего юзера) отображается (на этой же форме) форма редактирования юзера!! здесь!! я запрашиваю соответствуещего юзера и заполняются поля имя логин и тд редактирую информацию и нажимаю кнопку выполняется код:
Код

public String editAction() {
        IndexControl indexControl = this.getIndexControl();
        this.user.setId(indexControl.getUserId());
        Session session = null;
        Transaction tx = null;
        try {
            
            session = HibernateSessionFactory.getSession();
            session.clear();
            tx = session.beginTransaction();
            User userr = (User) session.createQuery(
            "from User as m where m.id=?").setLong(
                    0, indexControl.getUserId())
            .uniqueResult();
            userr = this.user;
            session.update(userr);
            tx.commit();
            FacesUtil.addMessage("User was edited.");
            // this.setAction("");
        } catch (Exception e) {
            tx.rollback();
            FacesUtil.addErrorMessage(e.getLocalizedMessage());
        }
        // setAction("add_action_success");
        return "";
    }


Здесь я попробывал получить юзера присвоить ему измененные значения и поместить его обратно в базу но опять та же ошибка:
a different object with the same identifier value was already associated with the session
раньше пытался просто 
Код

public String editAction() {
        IndexControl indexControl = this.getIndexControl();
        this.user.setId(indexControl.getUserId());
        Session session = null;
        Transaction tx = null;
        try {
            
            session = HibernateSessionFactory.getSession();
            session.clear();
            tx = session.beginTransaction();
            session.update(user);
            tx.commit();
            FacesUtil.addMessage("User was edited.");
            // this.setAction("");
        } catch (Exception e) {
            tx.rollback();
            FacesUtil.addErrorMessage(e.getLocalizedMessage());
        }
        // setAction("add_action_success");
        return "";
    }


Помогите пожалуйста.
Впринципе понятно что взят один юзер потом я изменяю его и хочу именного его проапдейтить от куда берется другой?
Нужен еще какой код допишу.

Автор: Kangaroo 6.11.2007, 13:18
Fedrus, 
а где ошибка вываливается?

Автор: Fedrus 6.11.2007, 13:36
Интересно получилось))
В пятницу сидел искал решение и дописал  session.clear(); всеравно, ошибка выбрасывалась на  session.update(user);(может плохо задиплоился проект)
Вобщем я искал решение дальше попробовал получать user и егоже и класть обратно (тут опять начала возникать эта ошибка) ))))
сегодня пришел уткнуся еще подумал и решил на форуме написать)) 
Сейчас просиш где ошибка вываливается убираю 
Код

 User userr = (User) session.createQuery(
            "from User as m where m.id=?").setLong(
                    0, indexControl.getUserId())
            .uniqueResult();
            userr = this.user;


иии нет ошибки ну я просто офигел сначало  smile  ну думаю чудеса)) но посмотрел получьше и вспомнил что добавленно 
 session.clear(); вот в тут то все и стало понятно хотя несовсем не доконца
Вот с clear работает но не моглибы расказать возможные проблеммы использования этого метода может есть другое решение))

Автор: mindflyer 9.11.2007, 19:02
Цитата(Fedrus @  6.11.2007,  12:21 Найти цитируемый пост)
Впринципе понятно что взят один юзер потом я изменяю его и хочу именного его проапдейтить от куда берется другой?

У тебя есть один объект, который "this.user" (назовём его первый) и второй, который ты взял из базы
Код
User userr = (User) session.createQuery  ...

Выполняя код 
Код
 userr = this.user; 

ты устанавливаешь ссылку userr на первый объект, т.е. теперь userr указывает на тот же объект, что и this.user (ну это очевидно).
И когда ты пытаешься сделать
Код
session.update(userr);

то ты отдаешь hibernate первый объект. Но у него в этой сессий уже есть второй объект с тем же id, о чём он тебе честно и говорит.

Если ты хочешь проапдейтить объект, то ты должен установить свойства именно у того объекта, который ты прочитал из базы данных.
Есть разные варианты, но проще всего просто скопировать свойства из this.user в userr.
Сразу через GUI редактировать объект, полученный из бд, не советую, т.к. в общем случае, чем меньше длится транзакция, тем лучше.
Также можешь глянуть документацию на методы merge и update в отношении detach объектов - твой первый объект как раз является detach объктом.

session.clear() - если кратко:  очищает кэш сессии, т.е. после вызова этого метода сессия "забывает" про ранее загруженные объекты.  Лучше его не использовать, если нет опыта работы с hibernate. (а когда он появится, то вряд ли возникнет необходимость его юзать smile )

Автор: YuryIlinikh 25.3.2008, 09:01
После выбора юзера закрой для него сессию и он станет detached после его можно менять, и делать update

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)