Гибернация слияния - PullRequest
       1

Гибернация слияния

10 голосов
/ 13 января 2012

Я тестирую hibernate и выдаю этот запрос

transaction = session.beginTransaction();
city = new City("A");
city  = (City)session.merge(city);
city.setName("B");
transaction.commit();

И я получаю эти запросы в командной строке:

Hibernate: insert into CITY (name) values (?)
Hibernate: update CITY set name=? where CITY_ID=?

Я использую объединение, а не сохранение, так почемуhibernate обновляет мой объект, он не должен обновляться.это правильно?В чем ошибка?

Ответы [ 3 ]

23 голосов
/ 13 января 2012

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

Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
User userA = (User)session.get(User.class, 1101);
transaction.commit();
session.close();
// Since session is closed, userA is detached.

session = sessionFactory.openSession();
transaction = session.beginTransaction();
User userB = (User)session.get(User.class, 1101);
//Now here,  userB represents the same persistent row as userA.
//When an attempt to reattach userA occurs, an exception is thrown
session.update(userA);
transaction.commit();
session.close();

Исключение при попытке присоединить отдельный объект, userA.

Exception in thread "main" org.hibernate.NonUniqueObjectException: a   
different object with the same identifier value was already associated
with the session:

This is because Hibernate is enforcing that only a single instance of a Persistent    object exists in memory.

Чтобы обойти вышеуказанную проблему, используется merge (), как показано ниже:

Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
User userA = (User)session.get(User.class, 1101);
transaction.commit();
session.close();
//userA is now detached as session is closed.

session = sessionFactory.openSession();
transaction = session.beginTransaction();
User userB = (User)session.get(User.class, 1101);
User userC = (User)session.merge(userA);
if (userB == userC) {
  System.out.println("Reattched user is equal");
}
transaction.commit();
session.close();
4 голосов
/ 13 января 2012

Это проблема секвенирования.На самом деле не проблема.Hibernate делает именно то, что вы сказали.Как говорит @TejasArjun, слияние - это слияние обнаруженных данных.вот что происходит:

...
city  = (City)session.merge(city); 
// No different to save(). Hibernate schedules an insert to the
// database to store the current record.

city.setName("B"); 
// The object is now flagged as dirty and needing to be saved. 
// Hiberate automatically tracks properties on objects and knows when they change.

transaction.commit(); 
// Hibernate sees that 'city' has been changed since it was saved, 
// so it schedules an update to store the new data.
0 голосов
/ 13 января 2012

Поскольку сессия еще не закрыта и в терминах сохранения city объект все еще присоединен к сессии.Таким образом, любые изменения в этом объекте будут прослушиваться сеансом гибернации, и будет вызываться соответствующий оператор dml.

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