简体   繁体   English

Hibernate合并

[英]Hibernate merge

I am testing hibernate and giving this query to 我正在测试hibernate并给出这个查询

transaction = session.beginTransaction();
city = new City("A");
city  = (City)session.merge(city);
city.setName("B");
transaction.commit();

And I am getting those queries in the command line: 我在命令行中收到这些查询:

Hibernate: insert into CITY (name) values (?)
Hibernate: update CITY set name=? where CITY_ID=?

I am using merge not save, so why hibernate is updating my object, It should not update. 我使用merge而不是save,所以为什么hibernate正在更新我的对象,它不应该更新。 am it right? 是吗? What is the mistake? 这是什么错误?

I will try to explain using a more concrete example. 我将尝试使用更具体的例子来解释。 Suppose you have a scenario like below : 假设您有如下情况:

Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
User userA = (User)session.get(User.class, 1101);
transaction.commit();
session.close();
// Since session is closed, userA is detached.

session = sessionFactory.openSession();
transaction = session.beginTransaction();
User userB = (User)session.get(User.class, 1101);
//Now here,  userB represents the same persistent row as userA.
//When an attempt to reattach userA occurs, an exception is thrown
session.update(userA);
transaction.commit();
session.close();

Exception when an attempt to reattach a Detached object, userA is made. 尝试重新挂接Detached对象时,发生userA。

Exception in thread "main" org.hibernate.NonUniqueObjectException: a   
different object with the same identifier value was already associated
with the session:

This is because Hibernate is enforcing that only a single instance of a Persistent    object exists in memory.

To get around the above problem, merge() is used, as shown below : 为了解决上述问题,使用了merge(),如下所示:

Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
User userA = (User)session.get(User.class, 1101);
transaction.commit();
session.close();
//userA is now detached as session is closed.

session = sessionFactory.openSession();
transaction = session.beginTransaction();
User userB = (User)session.get(User.class, 1101);
User userC = (User)session.merge(userA);
if (userB == userC) {
  System.out.println("Reattched user is equal");
}
transaction.commit();
session.close();

It's a sequencing issue. 这是一个排序问题。 Actually not an issue. 其实不是问题。 Hibernate is doing exactly what you told it to do. Hibernate完全按照你的要求去做。 As @TejasArjun says, merge is about merging in deteched data. 正如@TejasArjun所说,merge是关于合并检测数据的。 here's what is going on: 这是发生了什么:

...
city  = (City)session.merge(city); 
// No different to save(). Hibernate schedules an insert to the
// database to store the current record.

city.setName("B"); 
// The object is now flagged as dirty and needing to be saved. 
// Hiberate automatically tracks properties on objects and knows when they change.

transaction.commit(); 
// Hibernate sees that 'city' has been changed since it was saved, 
// so it schedules an update to store the new data.

Because session is not closed yet and in persistence terms city object is still attached to session. 因为会话尚未关闭,并且在持久性条款中, city对象仍然附加到会话。 So, any changes in that object will be listened by hibernate session and appropriate dml statement will be invoked. 因此,hibernate会话将监听该对象中的任何更改,并将调用适当的dml语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM