有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java重新附加分离的实例:hibernate lock()

我有点困惑。我不明白为什么在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).


共 (1) 个答案

  1. # 1 楼答案

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

    这是预期的行为,因为item对象是分离的,分离的对象不受automatic dirty checking的约束,所以在这种特定状态下不会将更改传播到数据库

    重新连接后:

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

    脏污检查将在冲洗时进行。当您重新附加一个实体时,Hibernate会发出一个SQL SELECT来获取最新的实体状态,它将在刷新时用于将其与内存中的对象数据进行比较

    这就是为什么在锁定之后(即使对于LockOptions.NONE),您会看到更改被传播

    如果对lock方法进行注释,则不会传播任何更改,因为第二个会话 不知道拆下的物品