Document directory
- I have been familiar with hibernate for a long time. The company's projects have been using ibatis. I encountered a problem when I was working on an external project yesterday:
I have been familiar with hibernate for a long time. The company's projects have been using ibatis. I encountered a problem when I was working on an external project yesterday:
laborPerson.setId(laborPersonId); ...
LaborPerson oldLaborPerson = (LaborPerson)getDao().getObjById(LaborPerson.class, laborPersonId); laborPerson.setCreateTime(oldLaborPerson.getCreateTime()); laborPerson.setCreateUser(oldLaborPerson.getCreateUser()); laborPerson.setUnit(oldLaborPerson.getUnit()); oldLaborPerson = null;
SaveOrupdate: the error "a different object with the same identifier value was already associated with the session" is reported.
In fact, I only want to modify the fields such as the Creation Time of the original old data. My friend told me to retrieve the old data and set it one by one. There are dozens of fields, I think there seems to be a way to merge it in the past. I tried it in an article and I can update it normally. (I Don't Need To saveOrupdate. I can directly judge whether to insert or update it based on the laborPersonId, update with merge), hibernate continues to explore...
if(StringUtil.isNotNullOrBlank(laborPersonId)) { LaborPerson oldLaborPerson = (LaborPerson)getDao().getObjById(LaborPerson.class, laborPersonId); laborPerson.setCreateTime(oldLaborPerson.getCreateTime()); laborPerson.setCreateUser(oldLaborPerson.getCreateUser()); ... HibernateUtil.getSession().merge(laborPerson); } else
{ laborPerson.setCreateTime(new Date()); laborPerson.setCreateUser(curUser); ... HibernateUtil.getSession().save(laborPerson); }
Original article: http://littie1987.iteye.com/blog/1039082
Merge () method of Hibernate
HibernateSQL
The following describes the Hibernate merge method. I plan to follow the three States of the hibernate object lifecycle.
1: If the pojo object is in the Free State, the Free State means that the id value of this object is null. Hibernate checks whether an object exists in the Database instead of looking at other information about the object, but whether the ID exists in the database. If the ID is null, it does not exist. Therefore, when we call the merge method, the insert operation is executed directly. This is a bit like the saveorupdate () method. Read a piece of code:
Java code
- User user = new user ();
- // User. setid (4 );
- User. setusername ("heyuanling2 ");
- User. setage (23 );
- User. setsex ("W ");
- User. setpassword ("heyuanling ");
- Session session = This. getsession ();
- Transaction TR = session. begintransaction ();
- // User exituser = (User) session. get (User. class, new Integer (1 ));
- Session. merge (user );
- Tr. commit ();
User user = new user (); // user. setid (4); User. setusername ("heyuanling2"); User. setage (23); User. setsex ("W"); User. setpassword ("heyuanling"); Session session = This. getsession (); transaction TR = session. begintransaction (); // user exituser = (User) session. get (user. class, new INTEGER (1); Session. merge (User); tr. commit ();
Let's look at the hibernate SQL statement:
Java code
- Hibernate:
- Select
- Max (id)
- From
- User _
- Hibernate:
- Insert
- Into
- User _
- (Username, password, sex, age, birthday, other, id)
- Values
- (?, ?, ?, ?, ?, ?, ?)
Hibernate: Select max (ID) from user_hibernate: insert into user _ (username, password, sex, age, birthday, other, ID) values (?, ?, ?, ?, ?, ?, ?)
Ii. unmanageable: if we put the code above // user. the comment of setid (4); is removed, so it becomes the object of detachment (in fact, it is so simple from the free to the tube, not as evil as officially said ...). Here is the SQL printing on the console:
Java code
- Hibernate:
- Select
- User0 _. id as id4_0 _,
- User0 _. username as username4_0 _,
- User0 _. password as password4_0 _,
- User0 _. sex as sex4_0 _,
- User0 _. age as age4_0 _,
- User0 _. birthday as birthday4_0 _,
- User0 _. other as other4_0 _
- From
- User _ user0 _
- Where
- User0 _. id =?
Hibernate: Select user0 _. ID as id4_0 _, user0 _. username as username4_0 _, user0 _. password as password4_0 _, user0 _. sex as sex4_0 _, user0 _. age as age4_0 _, user0 _. birthday as birthday4_0 _, user0 _. other as other4_0 _ from user _ user0 _ Where user0 _. id =?
No. Because the ID is not empty, Hibernate will not insert any more. Because the information of this object is the same as that in the database, Hibernate only executes a SELECT statement and does not update it. If we change the field value slightly, the SQL statement printed on the console should also have an update statement. In this case, merge also has the same method as saveorupdate.
3. Persistence: better understanding of persistence. If we get a record from the database, the record will be in the persistent state. If we call merge again, Hibernate will first determine whether the record has been modified, and if there is no record, it will do nothing, update after modification. This is a bit like saveorupdate.
Java code
- Session session = this. getSession ();
- Transaction tr = session. beginTransaction ();
- User exituser = (User) session. get (User. class, new Integer (1 ));
- Exituser. setAge (11 );
- Session. merge (exituser );
- Tr. commit ();
- Session. close ();
Session session = This. getsession (); transaction TR = session. begintransaction (); User exituser = (User) session. get (user. class, new INTEGER (1); exituser. setage (11); Session. merge (exituser); tr. commit (); Session. close ();
Check the result in the console again:
Java code
- Hibernate:
- Select
- User0 _. ID as id4_0 _,
- User0 _. Username as username4_0 _,
- User0 _. Password as password4_0 _,
- User0 _. Sex as sex4_0 _,
- User0 _. Age as age4_0 _,
- User0 _. Birthday as birthday4_0 _,
- User0 _. Other as other4_0 _
- From
- User _ user0 _
- Where
- User0 _. id =?
- Hibernate:
- Update
- User _
- Set
- Username = ?,
- Password = ?,
- Sex = ?,
- Age = ?,
- Birthday = ?,
- Other =?
- Where
- Id =?
Hibernate: select user0 _. id as id4_0 _, user0 _. username as username4_0 _, user0 _. password as password4_0 _, user0 _. sex as sex4_0 _, user0 _. age as age4_0 _, user0 _. birthday as birthday4_0 _, user0 _. other as other4_0 _ from user _ user0 _ where user0 _. id =? Hibernate: update user _ set username = ?, Password = ?, Sex = ?, Age = ?, Birthday = ?, Other =? Where id =?
If the record is not modified, there will be no subsequent update statement.
So what is the difference between merge and saveorupdate? Read a piece of code:
Java code
- Session session = this. getSession ();
- Transaction tr = session. beginTransaction ();
- User exituser = (User) session. get (User. class, new Integer (1 ));
- Tr. commit ();
- Session. close ();
- Session = getSession ();
- Tr = session. beginTransaction ();
- User exituser2 = (User) session. get (User. class, new Integer (1 ));
- Session. update (exituser );
- Tr. commit ();
- Session. Close ();
Session session = this. getSession (); Transaction tr = session. beginTransaction (); User exituser = (User) session. get (User. class, new Integer (1); tr. commit (); session. close (); session = getSession (); tr = session. beginTransaction (); User exituser2 = (User) session. get (User. class, new Integer (1); session. update (exituser); tr. commit (); session. close ();
Running the above Code, Hibernate reported an error: a different object with the same Identifier value was already associated with the session. This means that two objects with the same identifiers are not allowed in the session cache. So what if I change update to merge? After changing to merge, everything is OK and runs normally. In fact, merge will merge the objects with the same identifiers before executing the update. The specific direction of the merge is to merge the objects with the same identifiers to exituser2.
Note: before execution, the merge method returns to the cache to check whether there is a corresponding record, that is, there is a SELECT statement. The purpose of executing the modify statement is to determine whether the object has been modified. Regardless of the update statement, an update statement is used directly.