Hibernate Session is the interface between java application and hibernate framework. Today we will look into Session important methods for saving and updating data in tables – save, saveOrUpdate, persist, update and merge.
Hibernate Session是Java應用程序和hibernate框架之間的接口。 今天,我們將考慮會議的重要方法保存和表更新數據- 保存 ,saveOrUpdate, 堅持 , 更新和合并 。
hibernate update、As the method name suggests, hibernate save() can be used to save entity to database. We can invoke this method outside a transaction, that’s why I don’t like this method to save data. If we use this without transaction and we have cascading between entities, then only the primary entity gets saved unless we flush the session.
顧名思義, hibernate save()可用于將實體保存到數據庫。 我們可以在事務外部調用此方法,這就是為什么我不喜歡此方法保存數據的原因。 如果我們在不使用事務的情況下使用它,并且在實體之間進行級聯,那么只有主實體會被保存, 除非我們刷新會話 。
For our testing purposes we have two entity beans – Employee
and Address
.
hibernate批量更新? 為了進行測試,我們有兩個實體Bean – Employee
和Address
。
package com.journaldev.hibernate.model;import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;import org.hibernate.annotations.Cascade;@Entity
@Table(name = "EMPLOYEE")
@Access(value=AccessType.FIELD)
public class Employee {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "emp_id")private long id;@Column(name = "emp_name")private String name;@Column(name = "emp_salary")private double salary;@OneToOne(mappedBy = "employee")@Cascade(value = org.hibernate.annotations.CascadeType.ALL)private Address address;//Getter setter methods@Overridepublic String toString() {return "Id= " + id + ", Name= " + name + ", Salary= " + salary+ ", {Address= " + address + "}";}}
package com.journaldev.hibernate.model;import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;@Entity
@Table(name = "ADDRESS")
@Access(value=AccessType.FIELD)
public class Address {@Id@Column(name = "emp_id", unique = true, nullable = false)@GeneratedValue(generator = "gen")@GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") })private long id;@Column(name = "address_line1")private String addressLine1;@Column(name = "zipcode")private String zipcode;@Column(name = "city")private String city;@OneToOne@PrimaryKeyJoinColumnprivate Employee employee;//Getter setter methods@Overridepublic String toString() {return "AddressLine1= " + addressLine1 + ", City=" + city+ ", Zipcode=" + zipcode;}
}
Here is a simple hibernate program where we are invoking save()
method in different cases.
這是一個簡單的Hibernate程序,在不同情況下,我們在其中調用save()
方法。
package com.journaldev.hibernate.main;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;import com.journaldev.hibernate.model.Address;
import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;public class HibernateSaveExample {public static void main(String[] args) {// Prep WorkSessionFactory sessionFactory = HibernateUtil.getSessionFactory();//save example - without transactionSession session = sessionFactory.openSession();Employee emp = getTestEmployee();long id = (Long) session.save(emp);System.out.println("1. Employee save called without transaction, id="+id);session.flush(); //address will not get saved without thisSystem.out.println("*****");//save example - with transactionTransaction tx1 = session.beginTransaction();Session session1 = sessionFactory.openSession();Employee emp1 = getTestEmployee();long id1 = (Long) session1.save(emp1);System.out.println("2. Employee save called with transaction, id="+id1);System.out.println("3. Before committing save transaction");tx1.commit();System.out.println("4. After committing save transaction");System.out.println("*****");//save example - existing row in tableSession session6 = sessionFactory.openSession();Transaction tx6 = session6.beginTransaction();Employee emp6 = (Employee) session6.load(Employee.class, new Long(20));//update some dataSystem.out.println("Employee Details="+emp6);emp6.setName("New Name");emp6.getAddress().setCity("New City");long id6 = (Long) session6.save(emp6);emp6.setName("New Name1"); // will get updated in databaseSystem.out.println("5. Employee save called with transaction, id="+id6);System.out.println("6. Before committing save transaction");tx6.commit();System.out.println("7. After committing save transaction");System.out.println("*****");// Close resourcessessionFactory.close();}public static Employee getTestEmployee() {Employee emp = new Employee();Address add = new Address();emp.setName("Test Emp");emp.setSalary(1000);add.setAddressLine1("Test address1");add.setCity("Test City");add.setZipcode("12121");emp.setAddress(add);add.setEmployee(emp);return emp;}
}
hibernate sessionfactory,When we execute above program, it produces following output.
當我們執行以上程序時,它會產生以下輸出。
Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
1. Employee save called without transaction, id=149
Hibernate: insert into ADDRESS (address_line1, city, zipcode, emp_id) values (?, ?, ?, ?)
*****
Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
2. Employee save called with transaction, id=150
3. Before committing save transaction
Hibernate: insert into ADDRESS (address_line1, city, zipcode, emp_id) values (?, ?, ?, ?)
4. After committing save transaction
*****
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
Employee Details=Id= 20, Name= Kumar1, Salary= 1000.0, {Address= AddressLine1= Test address1, City=Blr, Zipcode=12121}
5. Employee save called with transaction, id=20
6. Before committing save transaction
Hibernate: update EMPLOYEE set emp_name=?, emp_salary=? where emp_id=?
Hibernate: update ADDRESS set address_line1=?, city=?, zipcode=? where emp_id=?
7. After committing save transaction
*****
Few important points that we can confirm from above output are:
我們可以從上述輸出中確認的幾個要點是:
Hibernate persist is similar to save (with transaction) and it adds the entity object to the persistent context, so any further changes are tracked. If the object properties are changed before the transaction is committed or session is flushed, it will also be saved into database.
Hibernate持久性類似于保存(帶有事務),并且將實體對象添加到持久性上下文中 ,因此可以跟蹤任何進一步的更改。 如果在提交事務或刷新會話之前更改了對象屬性,則該對象屬性還將保存到數據庫中。
Second difference is that we can use persist()
method only within the boundary of a transaction, so it’s safe and takes care of any cascaded objects.
第二個區別是我們只能在事務的邊界內使用persist()
方法,因此它是安全的,并且可以處理任何級聯對象。
Finally, persist doesn’t return anything so we need to use the persisted object to get the generated identifier value. Let’s look at hibernate persist with a simple program.
最后,persist不返回任何內容,因此我們需要使用persisted對象來獲取生成的標識符值。 讓我們看一下使用簡單程序保持Hibernate狀態。
package com.journaldev.hibernate.main;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;public class HibernatePersistExample {public static void main(String[] args) {// Prep WorkSessionFactory sessionFactory = HibernateUtil.getSessionFactory(); //persist example - with transactionSession session2 = sessionFactory.openSession();Transaction tx2 = session2.beginTransaction();Employee emp2 = HibernateSaveExample.getTestEmployee();session2.persist(emp2);System.out.println("Persist called");emp2.setName("Kumar"); // will be updated in database tooSystem.out.println("Employee Name updated");System.out.println("8. Employee persist called with transaction, id="+emp2.getId()+", address id="+emp2.getAddress().getId());tx2.commit();System.out.println("*****");// Close resourcessessionFactory.close();}}
Output produced by above code is:
上面的代碼產生的輸出是:
Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
8. Employee persist called with transaction, id=158, address id=158
Hibernate: insert into ADDRESS (address_line1, city, zipcode, emp_id) values (?, ?, ?, ?)
Hibernate: update EMPLOYEE set emp_name=?, emp_salary=? where emp_id=?
*****
Notice that first employee object is inserted, then at the time of transaction commit, update query is executed to update the name value. Also mapped object address is saved into database.
請注意,首先插入了雇員對象,然后在提交事務時執行更新查詢以更新名稱值。 映射的對象地址也保存到數據庫中。
Hibernate saveOrUpdate results into insert or update queries based on the provided data. If the data is present in the database, update query is executed.
Hibernate saveOrUpdate結果根據提供的數據插入或更新查詢。 如果數據庫中存在數據,則執行更新查詢。
We can use saveOrUpdate()
without transaction also, but again you will face the issues with mapped objects not getting saved if session is not flushed.
我們也可以在不使用事務的情況下使用saveOrUpdate()
,但是如果會話未刷新,您將再次遇到映射對象無法保存的問題。
Hibernate saveOrUpdate adds the entity object to persistent context and track any further changes. Any further changes are saved at the time of committing transaction, like persist.
Hibernate saveOrUpdate將實體對象添加到持久性上下文中并跟蹤任何進一步的更改。 提交事務時將保存所有進一步的更改,例如persist。
package com.journaldev.hibernate.main;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;public class HibernateSaveOrUpdateExample {public static void main(String[] args) {// Prep WorkSessionFactory sessionFactory = HibernateUtil.getSessionFactory();//saveOrUpdate example - without transactionSession session5 = sessionFactory.openSession();Employee emp5 = HibernateSaveExample.getTestEmployee();session5.saveOrUpdate(emp5);System.out.println("*****");//saveOrUpdate example - with transactionSession session3 = sessionFactory.openSession();Transaction tx3 = session3.beginTransaction();Employee emp3 = HibernateSaveExample.getTestEmployee();session3.saveOrUpdate(emp3);emp3.setName("Kumar"); //will be saved into DBSystem.out.println("9. Before committing saveOrUpdate transaction. Id="+emp3.getId());tx3.commit();System.out.println("10. After committing saveOrUpdate transaction");System.out.println("*****");Transaction tx4 = session3.beginTransaction();emp3.setName("Updated Test Name"); //Name changedemp3.getAddress().setCity("Updated City");session3.saveOrUpdate(emp3);emp3.setName("Kumar"); //again changed to previous value, so no Employee updateSystem.out.println("11. Before committing saveOrUpdate transaction. Id="+emp3.getId());tx4.commit();System.out.println("12. After committing saveOrUpdate transaction");System.out.println("*****");// Close resourcessessionFactory.close();}
}
Above program produces following output.
上面的程序產生以下輸出。
Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
*****
Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
9. Before committing saveOrUpdate transaction. Id=166
Hibernate: insert into ADDRESS (address_line1, city, zipcode, emp_id) values (?, ?, ?, ?)
Hibernate: update EMPLOYEE set emp_name=?, emp_salary=? where emp_id=?
10. After committing saveOrUpdate transaction
*****
11. Before committing saveOrUpdate transaction. Id=166
Hibernate: update ADDRESS set address_line1=?, city=?, zipcode=? where emp_id=?
12. After committing saveOrUpdate transaction
*****
Notice that without transaction, only Employee gets saved and address information is lost.
請注意,如果沒有交易,則只會保存員工,而地址信息會丟失。
With transaction employee object is tracked for any changes, thats why in last call there is no update in Employee table even though the value was changed in between, final value remains same.
使用事務雇員對象跟蹤是否有任何更改,這就是為什么即使在兩次調用之間值都發生了更改的情況下,在上次調用中Employee表中也沒有更新,所以最終值保持不變的原因。
Hibernate update should be used where we know that we are only updating the entity information. This operation adds the entity object to persistent context and further changes are tracked and saved when transaction is committed. Let’s check this behavior with a simple program.
當我們知道我們僅更新實體信息時,應使用Hibernate更新 。 此操作將實體對象添加到持久性上下文中 ,并且在提交事務時跟蹤并保存進一步的更改。 讓我們用一個簡單的程序檢查這種行為。
package com.journaldev.hibernate.main;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;public class HibernateUpdateExample {public static void main(String[] args) {// Prep WorkSessionFactory sessionFactory = HibernateUtil.getSessionFactory();Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();Employee emp = (Employee) session.load(Employee.class, new Long(101));System.out.println("Employee object loaded. " + emp);tx.commit();// update exampleemp.setName("Updated name");emp.getAddress().setCity("Bangalore");Transaction tx7 = session.beginTransaction();session.update(emp);emp.setName("Final updated name");System.out.println("13. Before committing update transaction");tx7.commit();System.out.println("14. After committing update transaction");// Close resourcessessionFactory.close();}}
When we execute above program for the first time, we get following output.
當我們第一次執行上面的程序時,我們得到以下輸出。
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
Employee object loaded. Id= 101, Name= Test Emp, Salary= 1000.0, {Address= AddressLine1= Test address1, City=Test City, Zipcode=12121}
13. Before committing update transaction
Hibernate: update EMPLOYEE set emp_name=?, emp_salary=? where emp_id=?
Hibernate: update ADDRESS set address_line1=?, city=?, zipcode=? where emp_id=?
14. After committing update transaction
On further execution, we get following output.
在進一步執行時,我們得到以下輸出。
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
Employee object loaded. Id= 101, Name= Final updated name, Salary= 1000.0, {Address= AddressLine1= Test address1, City=Bangalore, Zipcode=12121}
13. Before committing update transaction
14. After committing update transaction
Notice that there are no updates fired after first execution because there are no update in values. Also notice the employee name is “Final updated name” that we set after invoking update() method. This confirms that hibernate was tracking the object for any changes and at the time of committing transaction, this value got saved.
請注意,因為值沒有更新,所以第一次執行后不會觸發更新。 還要注意,員工名稱是我們在調用update()方法后設置的“最終更新名稱”。 這確認了Hibernate狀態正在跟蹤對象的任何更改,并且在提交事務時,該值已保存。
Hibernate merge can be used to update existing values, however this method create a copy from the passed entity object and return it. The returned object is part of persistent context and tracked for any changes, passed object is not tracked. This is the major difference with merge() from all other methods. Let’s look at this with a simple program.
Hibernate merge可用于更新現有值,但是此方法從傳遞的實體對象創建一個副本并將其返回。 返回的對象是持久性上下文的一部分,并跟蹤任何更改,不跟蹤傳遞的對象。 這是與其他所有方法的merge()的主要區別。 讓我們用一個簡單的程序來看一下。
package com.journaldev.hibernate.main;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;public class HibernateMergeExample {public static void main(String[] args) {// Prep WorkSessionFactory sessionFactory = HibernateUtil.getSessionFactory();Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();Employee emp = (Employee) session.load(Employee.class, new Long(101));System.out.println("Employee object loaded. " + emp);tx.commit();//merge example - data already present in tablesemp.setSalary(25000);Transaction tx8 = session.beginTransaction();Employee emp4 = (Employee) session.merge(emp);System.out.println(emp4 == emp); // returns falseemp.setName("Test");emp4.setName("Kumar");System.out.println("15. Before committing merge transaction");tx8.commit();System.out.println("16. After committing merge transaction");// Close resourcessessionFactory.close();}}
Output in first execution is:
第一次執行的輸出是:
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
Employee object loaded. Id= 101, Name= Final updated name, Salary= 1000.0, {Address= AddressLine1= Test address1, City=Bangalore, Zipcode=12121}
false
15. Before committing merge transaction
Hibernate: update EMPLOYEE set emp_name=?, emp_salary=? where emp_id=?
16. After committing merge transaction
In further execution, output produced is:
在進一步執行中,產生的輸出為:
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
Employee object loaded. Id= 101, Name= Kumar, Salary= 25000.0, {Address= AddressLine1= Test address1, City=Bangalore, Zipcode=12121}
false
15. Before committing merge transaction
16. After committing merge transaction
Notice that the entity object returned by merge() is different from the passed entity. Also notice that in further execution, name is “Kumar”, this is because the returned object is tracked for any changes.
請注意,merge()返回的實體對象與傳遞的實體不同。 還要注意,在進一步執行中,名稱為“ Kumar”,這是因為跟蹤返回的對象是否有任何更改。
That’s all for Hibernate Session save
and update
methods, I hope that examples above will help you in clarifying any doubts you have.
這就是Hibernate Session save
和update
方法的全部內容,我希望上面的示例將幫助您澄清您的任何疑問。
翻譯自: https://www.journaldev.com/3481/hibernate-session-merge-vs-update-save-saveorupdate-persist-example
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态