我有点困惑。我不明白为什么在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将再次管理持久对象。 当然,对象在托管持久性中进行的任何修改 state需要更新数据库。 我们将在下一章讨论Hibernate锁模式。通过指定Lock- Mode.NONE在这里,你告诉Hibernate不要执行版本检查或获取任何版本 将对象与Session重新关联时的数据库级锁定。如果你指定了 LockMode.READ或LockMode.UPGRADE,Hibernate会执行SELECT 语句以执行版本检查(并锁定数据库中的行) 更新)。
答案 0 :(得分: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),您会看到传播的更改。
如果您对lock方法发表评论,那么自第二个会话以来,不会传播任何更改 不知道分离的项目。