【发布时间】:2015-02-27 14:40:05
【问题描述】:
我有点困惑。我不明白为什么 lock()/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
在这种情况下,确实在对象之前或之后进行更改 被重新连接。在调用 lock() 之前所做的更改不会传播到 数据库,只有在确定分离的实例没有被删除时才使用它 修改的。此方法仅保证对象的状态从 分离到持久化,Hibernate 将再次管理持久化对象。 当然,一旦对象处于托管持久状态,您对它所做的任何修改 状态需要更新数据库。 我们将在下一章讨论 Hibernate 锁定模式。通过指定锁定- Mode.NONE 在这里,你告诉 Hibernate 不要执行版本检查或获取任何 将对象与 Session 重新关联时的数据库级锁。如果您指定 LockMode.READ 或 LockMode.UPGRADE,Hibernate 将执行 SELECT 语句以执行版本检查(并锁定数据库中的行) 用于更新)。
【问题讨论】:
-
不应该是
sessionTwo.buildLockRequest(LockOptions.NONE).lock(item);吗? -
是的,忘记了。这本书正在使用已弃用的方法 lock()。
-
您是否尝试在调试器中单步执行您的代码?告诉 hibernate 输出 SQL 语句,这样您就可以看到更改写入数据库的时间。
-
我打开了
hibernate.show_sql。它会进行选择,而不仅仅是在事务提交时进行更新。 InitialPrice 不应更新。我修改了这本书的例子,看看它是否确实如此。所以 lock() 重新附加了分离的对象,但是为什么书中说在锁定之前所做的更改不会传播,但在这种情况下它会传播。
标签: java hibernate jpa transactions locking