Строка была обновлена ​​или удалена другой транзакцией (или сопоставление несохраненных значений было неверным).

У меня есть проект Java, который работает на веб-сервере. Я всегда попадаю в это исключение.

Я прочитал некоторую документацию и обнаружил, что пессимистическая блокировка (или оптимистичная, но я читал, что пессимистическая лучше) — лучший способ предотвратить это исключение.

Но я не смог найти четкого примера, объясняющего, как его использовать.

Мой метод похож на:

    @Transactional
    public void test(Email email, String subject) {
        getEmailById(String id);
        email.setSubject(subject);
        updateEmail(email);
    }

пока:

  • Email — это класс Hibernate (это будет таблица в базе данных)
  • getEmailById(String id) — это функция, которая возвращает email (этот метод не имеет аннотации @Transactional)
  • updateEmail(email): это метод обновления электронной почты.

Примечание. Я использую Hibernate для сохранения, обновления и т. д. (пример: session.getcurrentSession.save(email))

Исключение:

ERROR 2011-12-21 15:29:24,910 Could not synchronize database state with session [myScheduler-1]
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [email#21]
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1792)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2435)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy130.generateEmail(Unknown Source)
    at com.admtel.appserver.tasks.EmailSender.run(EmailNotificationSender.java:33)
    at com.admtel.appserver.tasks.EmailSender$$FastClassByCGLIB$$ea0d4fc2.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:55)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:50)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:50)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
    at com.admtel.appserver.tasks.EmailNotificationSender$$EnhancerByCGLIB$$33eb7303.run(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
    at org.springframework.scheduling.support.MethodInvokingRunnable.run(MethodInvokingRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
ERROR 2011-12-21 15:29:24,915 [ exception thrown < EmailNotificationSender.run() > exception message Object of class [Email] with identifier [211]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Email#21] with params ] [myScheduler-1]
org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Object of class [Email] with identifier [21]: optimistic locking failed; nested exception is 

person Georgian Citizen    schedule 27.12.2011    source источник
comment
Вы уверены, что база данных не обновляется из нескольких мест, и ваш код единственный, кто делает это? Также к вашему методу test(Email email, String Subject) обращаются одновременно?   -  person Santosh    schedule 27.12.2011
comment
Я использую базу данных postgre. нет, мой проект все еще находится на стадии тестирования только на моем компьютере, поэтому никто не может получить к нему доступ, я единственный, кто обновляет данные в базе данных, я создаю службу, которая автоматически вызывает этот метод каждые 30 секунд, эта служба является уникальной службой, которая вызывает этот метод   -  person Georgian Citizen    schedule 28.12.2011


Ответы (18)


Пессимистическая блокировка, как правило, не рекомендуется, и это очень дорого с точки зрения производительности на стороне базы данных. Проблема, о которой вы упомянули (часть кода), не совсем ясна, например:

  • Если к вашему коду одновременно обращаются несколько потоков.
  • Как вы создаете объект session (не уверен, что используете Spring)?

Hibernate Объекты сеанса НЕ являются потокобезопасными. Поэтому, если есть несколько потоков, обращающихся к одному и тому же сеансу и пытающихся обновить один и тот же объект базы данных, ваш код потенциально может оказаться в подобной ситуации с ошибкой.

Итак, здесь происходит то, что более чем один поток пытается обновить один и тот же объект, один поток преуспевает, и когда следующий поток переходит к фиксации данных, он видит, что он уже был изменен, и в конечном итоге выдает StaleObjectStateException.

ИЗМЕНИТЬ:

Есть способ использовать пессимистическую блокировку в Hibernate. Перейдите по этой ссылке. Но, кажется, есть некоторые проблемы с этим механизмом. Однако я обнаружил ошибку в спящем режиме (HHH-5275). Сценарий, упомянутый в ошибке, выглядит следующим образом:

Два потока читают одну и ту же запись базы данных; один из этих потоков должен использовать пессимистическую блокировку, тем самым блокируя другой поток. Но оба потока могут прочитать запись базы данных, что приведет к сбою теста.

Это очень близко к тому, с чем вы столкнулись. Пожалуйста, попробуйте это, если это не сработает, единственный способ, который я могу придумать, это использовать Собственные SQL-запросы, где вы можете достичь пессимистическая блокировка в базе данных postgres с SELECT FOR UPDATE запросом.

person Santosh    schedule 27.12.2011
comment
я знаю это, поэтому мне нужно заблокировать базу данных, пока текущий сеанс не завершит свое обновление. как я могу заблокировать базу данных (оптимистично/пессимистично)? пожалуйста, до меня по коду, если вы можете. Я использую Spring, но это небольшой пример из моего проекта. Благодарность - person Georgian Citizen; 28.12.2011
comment
Поскольку ваше решение заняло первое место в результатах поиска, мне захотелось спросить вас, что вы имеете в виду: один поток успешен. Этот поток фиксирует сущность или нет? - person Stephane; 30.09.2015
comment
да. Успех означает, что поток смог завершить транзакцию (или зафиксировать объект). - person Santosh; 01.10.2015
comment
Под «сущностью» вы имели в виду ту же строку в базе данных, а не таблицу. Правильно? - person Aseem Goyal; 29.03.2017
comment
да. Я имел в виду то же самое. - person Santosh; 30.03.2017

Я знаю, что это старый вопрос, но некоторые из нас все еще задаются им и смотрят на небо, задаваясь вопросом, как это сделать. Вот одна из проблем, с которыми я столкнулся.

У нас есть менеджер очередей, который опрашивает данные и отдает их обработчикам для обработки. Чтобы избежать повторного захвата одних и тех же событий, администратор очередей блокирует запись в базе данных с состоянием LOCKED.

    void poll() {
        record = dao.getLockedEntity();
        queue(record);
    }

этот метод не был транзакционным, но dao.getLockedEntity() был транзакционным с REQUIRED.

Все хорошо, и в дороге, после нескольких месяцев производства, он вышел из строя с оптимистичным исключением блокировки.

После долгих отладок и проверки деталей мы могли обнаружить, что кто-то изменил код следующим образом:

    @Transactional(propagation=Propagation.REQUIRED, readOnly=false)
    void poll() {
        record = dao.getLockedEntity();
        queue(record);              
    }

Таким образом, запись была поставлена ​​в очередь еще до того, как транзакция в dao.getLockedEntity() была зафиксирована (она использует ту же транзакцию метода опроса), и объект был изменен ниже обработчиками (разными потоками) к тому времени, когда транзакция метода poll() была зафиксирована.

Мы исправили проблему, и теперь все выглядит хорошо.

Я подумал о том, чтобы поделиться им, потому что оптимистичные исключения блокировки могут сбивать с толку и их трудно отлаживать. Может кому пригодится мой опыт.

С уважением, Люйю

person Lyju I Edwinson    schedule 27.09.2013
comment
что вы подразумеваете под «Обязательным» рядом с «@Transactional»? - person tk_; 01.03.2018
comment
это распространение, я просто не ввел все это там, на самом деле это @Transactional(propagation = Propagation.REQUIRED) Пожалуйста, проверьте docs.spring.io/spring/docs/4.2.x/spring-framework-reference/ - person Lyju I Edwinson; 01.03.2018
comment
Как вы решили проблему? Было ли это добавлением @Transactional(propagation=Propagation.REQUIRED, readOnly=false) или удалением? Это я не совсем понял, извиняюсь. - person Dish; 21.06.2018
comment
Удалив @Transactional в методе опроса, это позволит завершить транзакцию в dao.getLockedEntity() до вызова метода очереди. Следовательно, объекты теперь могут быть изменены обработчиками задач, когда они поставлены в очередь с использованием метода очереди, поскольку транзакция уже завершена, а объекты отсоединены от сеанса гибернации, созданного с помощью dao.getLockedEntity(). - person Lyju I Edwinson; 14.01.2020

Похоже, вы на самом деле используете не электронную почту, которую вы извлекаете из базы данных, а более старую копию, которую вы получаете в качестве параметра. Что бы ни использовалось для контроля версий в строке, оно изменилось между моментом извлечения предыдущей версии и моментом обновления.

Вероятно, вы хотите, чтобы ваш код выглядел примерно так:

    @Transactional
    public void test(String id, String subject) {
       Email email = getEmailById(id);
       email.setSubject(subject);
       updateEmail(email);
    }
person tvanfosson    schedule 27.12.2011
comment
наверняка проблема в версии. но это изменение в методе не повлияло на то, что я пробовал это решение более одного раза. если у вас есть другое решение, пожалуйста, опубликуйте его здесь, спасибо - person Georgian Citizen; 28.12.2011

У меня была эта проблема в моем проекте.

После того, как я реализовал оптимистическую блокировку, я получил такое же исключение. Моя ошибка заключалась в том, что я не удалил сеттер поля, которое стало @Version. Поскольку сеттер вызывался в пространстве java, значение поля больше не соответствовало значению, сгенерированному БД. Таким образом, в основном поля версии больше не совпадали. На тот момент любая модификация сущности приводила к:

org.hibernate.StaleObjectStateException: строка была обновлена ​​или удалена другой транзакцией (или сопоставление несохраненных значений было неправильным)

Я использую H2 в БД памяти и Hibernate.

person MF Wolf    schedule 09.02.2015

Это исключение, вероятно, вызвано оптимистичной блокировкой (или ошибкой в ​​вашем коде). Вы, вероятно, используете его, не зная. И ваш псевдокод (который следует заменить реальным кодом, чтобы иметь возможность диагностировать проблему) неверен. Hibernate автоматически сохраняет все изменения, внесенные в прикрепленные объекты. Вы никогда не должны вызывать обновление, слияние или saveOrUpdate для прикрепленного объекта. Просто сделать

Email email = session.get(emailId);
email.setSubject(subject);

Нет необходимости вызывать обновление. Hibernate автоматически сбросит изменения перед фиксацией транзакции.

person JB Nizet    schedule 27.12.2011
comment
это не основная проблема. функция обновления не вызывает эту ошибку. я хочу использовать оптимистическую или пессимистическую блокировку в своем проекте, как я могу использовать их в качестве своего сценария? Благодарность - person Georgian Citizen; 28.12.2011
comment
оптимистическая блокировка заключается в обнаружении того, что другая транзакция обновила/удалила ту же строку, и выдаче исключения, которое вы получаете в этом случае. Если у вас есть поле версии, вы уже используете оптимистическую блокировку, и это вызывает исключение. Пессимистическая блокировка сделает ваше приложение медленным и подверженным взаимоблокировкам. Смиритесь с этим: если несколько пользователей обновляют одни и те же строки, один из них получит исключение. Это нормально и ожидаемо. - person JB Nizet; 28.12.2011
comment
это не нормально, если несколько пользователей обновляют одну и ту же строку и один получает исключение, потому что пользователи в других функциях обновляют баланс. если один пользователь получает исключение, баланс не обновляется. теперь я единственный, кто получает доступ к этой программе, и я получаю это исключение без доступа к нему нескольких пользователей, что произойдет, если к нему будут обращаться многие пользователи. Вы знаете, как я могу использовать пессимистическую блокировку? - person Georgian Citizen; 28.12.2011
comment
Если вы единственный, кто имеет доступ к базе данных, и вы получаете это исключение, то у вас есть проблема в вашем коде. Покажи нам свой код. Наличие исключений ожидаемо и нормально, если у вас есть несколько одновременных пользователей в одной строке. Перехватите исключение и сообщите пользователю, что его операция не удалась, что он должен обновить и повторить попытку. - person JB Nizet; 28.12.2011

У меня была та же проблема, и в моем случае проблема отсутствовала и/или неправильная реализация equals для некоторых типов полей в объекте объекта. Во время фиксации Hibernate проверяет ВСЕ объекты, загруженные в сеанс, чтобы проверить, не загрязнены ли они. Если какой-либо из сущностей грязный, спящий режим пытается их сохранить - независимо от того факта, что фактический объект, для которого запрашивается операция сохранения, не связан с другими сущностями.

Загрязнение объекта выполняется путем сравнения каждого свойства данного объекта (с их методами равенства) или UserType.equals, если свойство имеет связанный org.Hibernate.UserType.

Еще одна вещь, которая меня удивила, заключалась в том, что в моей транзакции (используя аннотацию Spring @Transactional) я имел дело с одним объектом. Hibernate жаловался на какой-то случайный объект, не связанный с сохранением этого объекта. Я понял, что есть самая внешняя транзакция, которую мы создаем на уровне контроллера REST, поэтому область сеанса слишком велика, и, следовательно, все объекты, когда-либо загруженные как часть обработки запроса, проверяются на загрязнение.

Надеюсь, это поможет кому-то, когда-нибудь.

Спасибо тряпки

person user2639828    schedule 27.11.2015
comment
Но почему сохранение других грязных сущностей является проблемой? - person Lubo Kanev; 27.04.2021

проверьте, существует ли объект в БД или нет, если он существует, получите объект и обновите его:

if (getEntityManager().contains(instance)) {
    getEntityManager().refresh(instance);
    return instance;
}

если это не соответствует приведенному выше условию... найдите объект с идентификатором в БД, выполните операцию, которая вам нужна, в этом случае точно будут отражены изменения.

if (....) {
    } else if (null != identity) {
        E dbInstance = (E) getEntityManager().find(instance.getClass(), identity);
        return dbInstance;
    }
person pavan    schedule 23.10.2012

У меня возникла одна и та же проблема в другом контексте моего проекта, и есть разные сценарии, такие как

 - object is accessed from various source like (server side and client)
 - without any interval accessing the same object from a different place

В первом случае

Когда я выдаю кал сервера, прежде чем сохранить этот объект, их один вызов из js и попытка сохранить и другое место, я понял, что вызов js происходит два, три раза (я думаю, что проблема привязки вызова вызывает проблему)

я решил

e.preventDefault()

Второй случай,

object.lock()
person Suganthan Madhavan Pillai    schedule 23.05.2014

Я тоже получал такое исключение, но проблема была в моем идентификаторе Entity. Я использую UUID, и есть некоторые проблемы в том, как с ними работает Spring. Поэтому я просто добавил эту строку в свой идентификатор объекта, и он начал работать:

@Column(columnDefinition = "BINARY(16)")

Здесь вы можете найти немного больше информации.

person Kamo Spertsian    schedule 10.01.2019
comment
Спасибо за этот очень полезный совет: это как раз решение проблемы, которая часами сводила меня с ума :) - person Francesco Galgani; 07.08.2020

На всякий случай, если кто-то проверил эту тему и столкнулся с такой же проблемой, как у меня...

Строка была обновлена ​​или удалена другой транзакцией (или сопоставление несохраненных значений было неверным).

Я использую NHibernate, я получил ту же ошибку при создании объекта...

Я передавал ключ вручную, а также указал генератор GUID в сопоставлении...

И спящий режим генерирует для меня точно такую ​​​​же ошибку, поэтому, как только я удалил GUID и оставил поле пустым, все прошло нормально.

Этот ответ может не помочь вам, но поможет кому-то вроде меня, который только что просмотрел вашу тему из-за той же ошибки.

person deadManN    schedule 25.01.2015

Эта ошибка возникла у меня, когда я пытался обновить одну и ту же строку из двух разных сеансов. Я обновил поле в одном браузере, в то время как второй был открыт и уже сохранил исходный объект в своем сеансе. Когда я попытался обновить этот второй «устаревший» сеанс, я получаю сообщение об ошибке устаревшего объекта. Чтобы исправить это, я повторно загружаю свой объект для обновления из базы данных, прежде чем установить значение для обновления, а затем сохраняю его как обычно.

person Roger    schedule 05.11.2014

Я также столкнулся с этой ошибкой при попытке обновить существующую строку после создания новой и провел целую вечность, ломая голову, копаясь в логике транзакций и версий, пока не понял, что я использовал неправильный тип для одной из моих строк. столбцы первичного ключа.

Я использовал LocalDate вместо LocalDateTime – я думаю, что это приводило к тому, что спящий режим не мог различать объекты, что приводило к этой ошибке.

После изменения ключа на LocalDateTime ошибка исчезла. Кроме того, обновление отдельных строк также стало работать — раньше не удалось найти строку для обновления, и тестирование этой отдельной проблемы на самом деле привело меня к моим выводам относительно сопоставления первичного ключа.

person Josh Manderson    schedule 01.04.2019

Не устанавливайте Id для объекта, который вы сохраняете, так как Id будет сгенерирован автоматически.

person w0ns88    schedule 14.06.2019

У меня были проблемы с одной и той же ошибкой в ​​​​более чем одном проекте Spring. Для меня общим решением было разделить мой метод службы, чтобы каждое действие INSERT, UPDATE и DELETE получило собственный метод с @Transactional. Я думаю, что эта проблема связана с внутренним управлением Spring, где взаимодействие с базой данных выполняется в конце метода, и, по моему мнению, это точка, в которой срабатывает исключение.

Обновление и дополнительные решения.

Моя проблема заключалась в том, что я запросил объект @Entity Class и изменил значение, не сохранив его, потому что, строго говоря, он был обновлен другим запросом (вне области действия), но поскольку этот объект был внутренним для сеансы в карте теперь имели другое значение, следующий запрос блокировался с этим сообщением.

Поэтому я создал переменную и сохранил там новые значения, а затем отправил их в UpdateQuery, чтобы Hibernate не регистрировал несохраненные изменения и строку можно было обновить. Hibernate, похоже, отправляет оператор блокировки в базу данных каждый раз, когда объект класса @Entity изменяется или, по крайней мере, локально пробивает строку по первичному ключу.

person BeatEngine    schedule 08.02.2021

У меня была такая же проблема в моем проекте Grails. Ошибка заключалась в том, что я перезаписывал метод получения поля коллекции. Это всегда возвращало новую версию коллекции в другом потоке.

class Entity {
    List collection

    List getCollection() {
        return collection.unique()
    }
}

Решение состояло в том, чтобы переименовать метод получения:

class Entity {
    List collection

    List getUniqueCollection() {
        return collection.unique()
    }
}
person moskauerst    schedule 04.05.2017

Чтобы предотвратить StaleObjectStateException, в файле hbm напишите следующий код:

<timestamp name="lstUpdTstamp" column="LST_UPD_TSTAMP" source="db"/>
person Yusuf    schedule 30.10.2015
comment
@Yusuf - Совет: чтобы код XML был виден, используйте кнопку кода {} на панели инструментов или сделайте отступ в строке четыре (4) пробела. - person Leigh; 31.10.2015
comment
Вы должны объяснить, что делает ваш код и как он решает вопрос. Хотя я не думаю, что это решение. - person Stealth Rabbi; 19.01.2017

Сначала проверьте свой импорт, когда вы используете сеанс, транзакция должна быть org.hibernate и удалите аннотацию @Transactinal. и самое главное в классе Entity, если вы использовали @GeneratedValue(strategy=GenerationType.AUTO) или любой другой, то во время создания объекта модели/создания объекта объекта не следует создавать идентификатор. Окончательный вывод: если вы хотите, чтобы идентификатор пропуска был подан, то есть PK, удалите @GeneratedValue из класса объектов.

person shubham bellale    schedule 24.10.2018

У меня была эта проблема в одном из моих приложений, теперь я знаю, что это старая тема, но вот мое решение; Изучив данные внутри отладчика, я понял, что JVM на самом деле не загружала их должным образом, когда Hibernate пытался обновить базу данных (что на самом деле делается в другом потоке), поэтому я добавил ключевое слово «volatile» в каждое поле. сущностей. У него есть некоторые проблемы с производительностью, но вместо того, чтобы бросать тяжелые объекты...

person Chiana    schedule 22.04.2015