Вы можете без проблем смешивать Hibernate Session и Entity Manager в одном приложении. EntityManagerImpl просто делегирует вызывает частный экземпляр SessionImpl .
То, что вы описываете, является аномалией конфигурации транзакции. Каждая транзакция базы данных выполняется изолированно (если вы не используете REAN_UNCOMMITED, что, я думаю, не так), но как только вы ее зафиксируете, изменения будут доступны из любой другой транзакции или соединения. Поэтому, как только транзакция зафиксирована, вы должны увидеть все изменения в любом другом сеансе Hibernate, соединении JDBC или даже в вашем инструменте управления пользовательским интерфейсом базы данных.
Вы сказали, что произошел конфликт первичного ключа. Этого не может произойти, если вы используете Hibernate Identity или генератор последовательности. Для старого генератора Hi-Lo у вас могут возникнуть проблемы, если внешнее соединение попытается вставить записи в ту же таблицу Hibernate использует старый генератор идентификаторов hi/lo.
Эта проблема также может возникнуть при наличии аномалии репликации мастер/мастер. Если у вас есть несколько узлов и нет репликации строгой согласованности, вы можете столкнуться с нарушениями ограничений первичного ключа.
Обновить
Решение 1:
При координации нового и старого кода, пытающегося вставить один и тот же объект, вы можете иметь логику выбора, чем вставки, работающую в транзакции SERIALIZABLE. Транзакция SERIALIZABLE получает соответствующие блокировки от имени тура, поэтому вы все еще можете иметь уровень изоляции READ_COMMITTED по умолчанию, в то время как только проблемные методы службы помечены как SERIALIZABLE.
Таким образом, как в старом коде, так и в новом коде эта логика запускает выборку для проверки, существует ли уже строка, удовлетворяющая ограничению выбора, только для ее вставки, если ничего не найдено. Уровень изоляции SERIALIZABLE предотвращает фантомное чтение, поэтому я думаю, что он должен предотвращать нарушения ограничений.
Решение 2:
Если вы готовы делегировать эту задачу JDBC, вы также можете изучить оператор MERGE SQL, если ваша текущая база данных поддерживает это. По сути, это операция upsert, выдающая обновление или вставку за кулисами. Эта команда намного привлекательнее, поскольку вы можете запускать ее даже при READ_COMMITTED. Единственным недостатком является то, что вы не можете использовать Hibernate для этого, и только некоторые базы данных поддерживают его.
person
Vlad Mihalcea
schedule
30.07.2014
EntityManager
(илиSessionFactory
изEntityManagerFactory
). - person Serge Ballesta   schedule 30.07.2014org.hibernate.SessionFactory
, вызываяorg.hibernate.cfg.Configuration.buildSessionFactory()
, а затемorg.hibernate.Session
, вызываяmySessionFactoryImpl.getCurrentSession()
. - person Alexander Rühl   schedule 04.08.2014EntityManager
вводится через@PersistenceContext
. Какие части XML могут быть дополнительно интересны? - person Alexander Rühl   schedule 04.08.2014buildSessionFactory
, см. мой ответ ниже. - person Serge Ballesta   schedule 04.08.2014