hibernate update,Hibernate Session合并,更新,保存,saveOrUpdate,持久化示例

 2023-11-19 阅读 24 评论 0

摘要: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 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會話 (Hibernate Session)

Hibernate會話保存 (Hibernate Session save)

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 – EmployeeAddress

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:

我們可以從上述輸出中確認的幾個要點是:

  • We should avoid save outside transaction boundary, otherwise mapped entities will not be saved causing data inconsistency. It’s very normal to forget flushing the session because it doesn’t throw any exception or warnings.

    我們應避免在事務邊界之外保存,否則將不會保存映射的實體,從而導致數據不一致。 忘記刷新會話非常正常,因為它不會引發任何異常或警告。
  • Hibernate save method returns the generated id immediately, this is possible because primary object is saved as soon as save method is invoked.

    Hibernate save方法立即返回生成的id,這是可能的,因為一旦調用save方法,就會保存主對象。
  • If there are other objects mapped from the primary object, they gets saved at the time of committing transaction or when we flush the session.

    如果從主對象映射了其他對象,則在提交事務時或在刷新會話時會保存它們。
  • For objects that are in persistent state, save updates the data through update query. Notice that it happens when transaction is committed. If there are no changes in the object, there wont be any query fired. If you will run above program multiple times, you will notice that update queries are not fired next time because there is no change in the column values.

    對于處于持久狀態的對象,保存將通過更新查詢來更新數據。 請注意,它在提交事務時發生。 如果對象沒有變化,則不會觸發任何查詢。 如果您將多次在該程序上運行,您會注意到下次不會觸發更新查詢,因為列值沒有變化。
  • Hibernate save load entity object to persistent context, if you will update the object properties after the save call but before the transaction is committed, it will be saved into database.

    Hibernate將加載實體對象保存到持久上下文中,如果您將在save調用之后但在提交事務之前更新對象屬性,則它將被保存到數據庫中。

冬眠堅持 (Hibernate Persist)

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.

請注意,首先插入了雇員對象,然后在提交事務時執行更新查詢以更新名稱值。 映射的對象地址也保存到數據庫中。

HibernatesaveOrUpdate (Hibernate saveOrUpdate)

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更新 (Hibernate update)

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合并 (Hibernate Merge)

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 saveupdate方法的全部內容,我希望上面的示例將幫助您澄清您的任何疑問。

翻譯自: https://www.journaldev.com/3481/hibernate-session-merge-vs-update-save-saveorupdate-persist-example

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/183160.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息