2014-12-31 6 views
1

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

В этом примере моя начальная цена установлена ​​и не должна обновляться в базе данных. Но он действительно обновляется, если я распечатаю его. Или все изменилось? Книга использует Hibernate 3, и я использую Hibernate v3.6.10.

Session session = HibernateUtil.getSessionFactory().openSession(); 
Transaction tx = session.beginTransaction(); 

Item item = (Item) session.get(Item.class, new Long(1)); 

tx.commit(); 
session.close(); 

Session sessionTwo = HibernateUtil.getSessionFactory().openSession(); 
Transaction tx2 = sessionTwo.beginTransaction(); 
// Changes made before the call to lock() aren’t propagated to the database 
item.setInitialPrice(new BigDecimal(179)); 

// sessionTwo.lock(item, LockMode.NONE); 
sessionTwo.buildLockRequest(LockOptions.NONE).lock(item); 
item.setDescription("This playstation 3 is in a fine state"); 
GregorianCalendar gc = new GregorianCalendar(); 
gc.setLenient(false); 
gc.set(2015, 0, 31, 9, 12, 34); 

item.setEndDate(gc.getTime()); 

item = (Item) sessionTwo.get(Item.class, new Long(1)); 

tx2.commit(); 
sessionTwo.close(); 

logger.debug(item.toString()); // still changes are made to initialPrice property 

От Java Persistence With Hibernate

В этом случае делает дело ли сделаны изменения до или после того, как объект был снова прикреплен. Изменения, внесенные до вызова функции блокировки(), не распространяются на базу данных , вы используете ее, только если вы уверены, что снятый экземпляр не был изменен . Этот метод гарантирует только то, что состояние объекта изменяется от отстоящего до постоянного, и что Hibernate снова будет управлять постоянным объектом. Конечно, любые изменения, внесенные вами в объект после того, как он находится в управляемом постоянном состоянии , требуют обновления базы данных. Обсудим режимы блокировки Hibernate в следующей главе. Указав Lock- Mode.NONE, вы указываете Hibernate не выполнять проверку версии или не получать любые блокировки на уровне базы данных при повторном соединении объекта с сеансом. Если вы указали LockMode.READ или LockMode.UPGRADE, Hibernate выполнил бы оператор SELECT для выполнения проверки версии (и для блокировки строк (строк) в базе данных для обновления).

+0

Не должно быть 'sessionTwo.buildLockRequest (LockOptions.NONE) .lock (item);'? – MPirious

+0

Да, забыл. В книге используется устаревшая блокировка метода(). – t0tec

+0

Вы пытались выполнить свой код в отладчике? Сообщите hibernate для вывода операторов SQL, чтобы вы могли видеть, когда изменения записываются в базу данных. – MPirious

ответ

1
//Changes made before the call to lock() aren’t propagated to the database 
item.setInitialPrice(new BigDecimal(179)); 

Это ожидаемое поведение, так как объект элемента отсоединяется, и отдельные объекты, не подлежат automatic dirty checking, так что никаких изменений не распространяются на базы данных, в данном конкретном состоянии.

После того, как вы приклеить ее:

sessionTwo.buildLockRequest(LockOptions.NONE).lock(item); 

грязная проверка будет применяться на время промывки. При повторной привязке объекта Hibernate выдает SQL SELECT для извлечения последнего состояния сущности, которое будет использоваться во время очистки для сравнения с данными объекта в памяти.

Именно поэтому после блокировки (даже для LockOptions.NONE) вы видите, что изменения распространяются.

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

+0

Я понимаю. Спасибо за разъяснения. – t0tec

+0

Добро пожаловать. –

Смежные вопросы