У меня есть два пользовательских объекта, и пока я пытаюсь сохранить объект, используя
session.save(userObj);
Я получаю следующую ошибку:
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
[com.pojo.rtrequests.User#com.pojo.rtrequests.User@d079b40b]
Я создаю сеанс, используя
BaseHibernateDAO dao = new BaseHibernateDAO();
rtsession = dao.getSession(userData.getRegion(),
BaseHibernateDAO.RTREQUESTS_DATABASE_NAME);
rttrans = rtsession.beginTransaction();
rttrans.begin();
rtsession.save(userObj1);
rtsession.save(userObj2);
rtsession.flush();
rttrans.commit();
rtsession.close(); // in finally block
Я также пробовал сделать session.clear()
перед сохранением, но все равно не повезло.
Это первый раз, когда я получаю объект сеанса, когда приходит запрос пользователя, поэтому я понимаю, почему я говорю, что этот объект присутствует в сеансе.
Какие-либо предложения?
Ответы:
У меня была эта ошибка много раз, и ее может быть довольно сложно отследить ...
По сути, спящий режим говорит о том, что у вас есть два объекта с одинаковым идентификатором (одним и тем же первичным ключом), но они не являются одним и тем же объектом.
Я бы посоветовал вам разбить свой код, т.е. закомментировать биты, пока ошибка не исчезнет, а затем вернуть код, пока он не вернется, и вы не найдете ошибку.
Чаще всего это происходит с помощью каскадных сохранений, когда между объектом A и B существует каскадное сохранение, но объект B уже связан с сеансом, но не находится в том же экземпляре B, что и объект A.
Какой генератор первичного ключа вы используете?
Причина, по которой я спрашиваю, заключается в том, что эта ошибка связана с тем, как вы указываете спящему режиму определить постоянное состояние объекта (то есть, является ли объект постоянным или нет). Ошибка могла возникнуть из-за того, что спящий режим пытается сохранить объект, который уже является постоянным. Фактически, если вы используете save, hibernate попытается сохранить этот объект, и, возможно, уже существует объект с таким же первичным ключом, связанный с сеансом.
пример
Предполагая, что у вас есть объект класса hibernate для таблицы с 10 строками на основе комбинации первичных ключей (столбец 1 и столбец 2). Итак, в какой-то момент вы удалили из таблицы 5 строк. Теперь, если вы снова попытаетесь добавить те же 10 строк, пока спящий режим пытается сохранить объекты в базе данных, 5 строк, которые уже были удалены, будут добавлены без ошибок. Теперь оставшиеся 5 строк, которые уже существуют, вызовут это исключение.
Таким образом, простой подход заключается в проверке того, обновили ли вы / удалили какое-либо значение в таблице, которое является частью чего-то, и позже вы пытаетесь снова вставить те же объекты
источник
Это только один момент, когда спящий режим создает больше проблем, чем решает. В моем случае есть много объектов с одинаковым идентификатором 0, потому что они новые и их нет. БД их генерирует. Где-то я читал, что 0 сигналов не задано. Интуитивно понятный способ сохранить их - перебрать их и сказать, что спящий режим сохраняет объекты. Но вы не можете этого сделать - «Конечно, вы должны знать, что спящий режим работает так и так, поэтому вы должны…» Итак, теперь я могу попробовать изменить идентификаторы на Long вместо long и посмотреть, работает ли он тогда. В конце концов, проще сделать это самостоятельно с помощью простого картографа, потому что спящий режим - это просто дополнительная непрозрачная нагрузка. Другой пример: попытка прочитать параметры из одной базы данных и сохранить их в другой вынуждает вас выполнять почти всю работу вручную.
источник
ИСПОЛЬЗОВАНИЕ
session.evict(object);
Функцияevict()
метода используется для удаления экземпляра из кеша сеанса. Итак, при первом сохранении объекта, сохраните объект, вызвавsession.save(object)
метод перед удалением объекта из кеша. Таким же образом обновите объект, вызвавsession.saveOrUpdate(object)
илиsession.update(object)
перед вызовом evict ().источник
Это может произойти, если вы использовали один и тот же объект сеанса для чтения и записи. Как? Допустим, вы создали одну сессию. Вы читаете запись из таблицы сотрудников с первичным ключом Emp_id = 101. Теперь вы изменили запись в Java. И вы собираетесь сохранить запись о сотруднике в базе данных. мы нигде не закрывали сессию. Поскольку прочитанный объект также сохраняется в сеансе. Он конфликтует с объектом, который мы хотим написать. Отсюда и возникает эта ошибка.
источник
Как кто-то уже указывал выше, я столкнулся с этой проблемой, когда у меня были
cascade=all
оба концаone-to-many
отношения, поэтому давайте предположим, что A -> B (один ко многим от A и многие к одному от B) и обновлял экземпляр B в A, а затем вызвал saveOrUpdate (A), это привело к циклическому запросу на сохранение, то есть к сохранению триггеров A, сохранению B, которое запускает сохранение A ... и в третьем случае, когда объект (A) пытался быть добавленным в sessionPersistenceContext, возникло исключение duplicateObject.Я мог бы решить эту проблему, убрав каскад с одного конца.
источник
Вы можете использовать
session.merge(obj)
, если выполняете сохранение с разными сеансами с постоянным объектом с одинаковым идентификатором.Это сработало, раньше у меня была такая же проблема.
источник
Я тоже столкнулся с этой проблемой, и мне было трудно найти ошибку.
У меня была следующая проблема:
Объект был прочитан Дао с другим сеансом гибернации.
Чтобы избежать этого исключения, просто перечитайте объект с помощью dao, которое будет сохранять / обновлять этот объект позже.
так:
Надеюсь, что это сэкономит людям много времени!
источник
Я столкнулся с этой проблемой:
Я решил это, сбросив результаты после удаления и очистив кеш перед сохранением нового объекта.
источник
Эта проблема возникает, когда мы обновляем тот же объект сеанса, который мы использовали для выборки объекта из базы данных.
Вы можете использовать метод слияния спящего режима вместо метода обновления.
например, сначала используйте session.get (), а затем вы можете использовать session.merge (объект). Этот метод не создаст никаких проблем. Мы также можем использовать метод merge () для обновления объекта в базе данных.
источник
Получите объект внутри сеанса, вот пример:
источник
Правильно ли сопоставлены ваши идентификаторы? Если база данных отвечает за создание идентификатора через идентификатор, вам необходимо сопоставить свой объект пользователя с этим ..
источник
Я столкнулся с этой проблемой при удалении объекта, ни выселение, ни очистка не помогли.
источник
до позиции, в которой начинаются повторяющиеся объекты, вы должны закрыть сеанс, а затем начать новый сеанс
таким образом, в одном сеансе не может быть более одной сущности с одним и тем же идентификатором.
источник
Поздно на вечеринку, но может помочь новым пользователям -
У меня возникла эта проблема, когда я выбираю запись с использованием
getsession()
и снова обновляю другую запись с тем же идентификатором, используя тот же сеанс, что вызывает проблему. Добавлен код ниже.Такого делать нельзя. Решение - либо удалить сеанс перед обновлением, либо изменить бизнес-логику.
источник
Проверьте, не забыли ли вы указать @GenerateValue для столбца @Id. У меня была такая же проблема с отношением многих ко многим между фильмом и жанром. Программа вызвала ошибку Hibernate: org.hibernate.NonUniqueObjectException: другой объект с таким же значением идентификатора уже был связан с ошибкой сеанса. Позже я узнал, что мне просто нужно убедиться, что у вас есть @GenerateValue для метода получения GenreId.
источник
просто проверьте идентификатор, принимает ли он ноль или 0, например
в добавлении или обновлении, где содержимое устанавливается из формы в Pojo
источник
Я новичок в NHibernate, и моя проблема заключалась в том, что я использовал другой сеанс для запроса моего объекта, чем для его сохранения. Таким образом, сеанс сохранения не знал об объекте.
Это кажется очевидным, но, читая предыдущие ответы, я везде искал 2 объекта, а не 2 сеанса.
источник
@GeneratedValue (strategy = GenerationType.IDENTITY), добавление этой аннотации к свойству первичного ключа в вашем entity-компоненте должно решить эту проблему.
источник
Я решил эту проблему.
На самом деле это происходит потому, что мы забыли о реализации свойства PK типа генератора в классе bean-компонента. Так что сделайте его любым, например, как
когда мы сохраняем объекты bean-компонента, каждый объект получает один и тот же идентификатор, поэтому первый объект сохраняется, когда другой объект для сохранения, то HIB FW через этот тип
Exception: org.hibernate.NonUniqueObjectException:
другого объекта с тем же значением идентификатора уже был связан с сеансом.источник
Проблема возникает из-за того, что в одном сеансе гибернации вы пытаетесь сохранить два объекта с одним и тем же идентификатором. Есть два решения: -
Это происходит потому, что вы неправильно настроили свой файл mapping.xml для полей id, как показано ниже: -
Перегрузите метод getsession, чтобы он принял параметр, например isSessionClear, и очистите сеанс перед возвратом текущего сеанса, как показано ниже.
Это приведет к очистке существующих объектов сеанса, и даже если спящий режим не генерирует уникальный идентификатор, при условии, что вы правильно настроили свою базу данных для первичного ключа, используя что-то вроде Auto_Increment, это должно сработать для вас.
источник
У меня была похожая проблема. В моем случае я забыл установить
increment_by
значение в базе данных таким же, как то, которое используется кнопкамиcache_size
иallocationSize
. (Стрелки указывают на указанные атрибуты)SQL:
Ява:
источник
В противном случае, чем сказал wbdarby , это может произойти даже, когда объект извлекается путем передачи идентификатора объекта в HQL. В случае попытки изменить поля объекта и сохранить его обратно в БД (изменение может быть вставкой, удалением или обновлением) в том же сеансе , появится эта ошибка. Попробуйте очистить сеанс гибернации перед сохранением измененного объекта или создайте новый сеанс.
Надеюсь, я помог ;-)
источник
У меня та же ошибка, при которой я заменял свой Сет новым, полученным от Джексона.
Чтобы решить эту проблему, я сохраняю существующий набор, удаляю из старого набора элемент, который неизвестен, в новый список
retainAll
. Затем добавляю новые с помощьюaddAll
.Нет необходимости иметь сеанс и манипулировать им.
источник
Попробуй это. Ниже сработало для меня!
В
hbm.xml
файлеНам нужно установить для
dynamic-update
атрибута тега класса значениеtrue
:Установите для атрибута class тега генератора в столбце unique значение
identity
:Примечание. Установите для уникального столбца значение,
identity
а неassigned
.источник
Еще одна вещь, которая сработала для меня, - это сделать переменную экземпляра Long вместо long
У меня был длинный идентификатор переменной первичного ключа; меняем его на Long id; работал
Всего наилучшего
источник
Вы всегда можете выполнить промывку сеанса. Flush синхронизирует состояние всех ваших объектов в сеансе (пожалуйста, поправьте меня, если я ошибаюсь), и, возможно, в некоторых случаях это решит вашу проблему.
Вам также может помочь реализация ваших собственных equals и hashcode.
источник
Вы можете проверить свои настройки каскада. Причиной этого могут быть настройки Cascade на ваших моделях. Я удалил настройки каскада (по сути, не разрешая каскадные вставки / обновления), и это решило мою проблему
источник
Я тоже обнаружил эту ошибку. Что сработало для меня, так это убедиться, что первичный ключ (который генерируется автоматически) не является PDT (например, long, int и т. Д.), А является объектом (например, Long, Integer и т. Д.)
Когда вы создаете свой объект для его сохранения, убедитесь, что вы передаете null, а не 0.
источник
Это помогает?
источник
Я решил подобную проблему:
источник