我有点困惑。我不明白为什么在 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
In this case, it does matter whether changes are made before or after the object has been reattached. Changes made before the call to lock() aren’t propagated to the database, you use it only if you’re sure the detached instance hasn’t been modified. This method only guarantees that the object’s state changes from detached to persistent and that Hibernate will manage the persistent object again. Of course, any modifications you make to the object once it’s in managed persistent state require updating of the database. We discuss Hibernate lock modes in the next chapter. By specifying Lock- Mode.NONE here, you tell Hibernate not to perform a version check or obtain any database-level locks when reassociating the object with the Session. If you specified LockMode.READ, or LockMode.UPGRADE, Hibernate would execute a SELECT statement in order to perform a version check (and to lock the row(s) in the database for updating).
最佳答案
//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),您会看到传播的更改。
如果您注释锁定方法,则不会传播任何更改,因为第二个 session 不知道分离的项目。
关于java - 重新附加分离的实例 : hibernate lock(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27722274/