Hibernate Session zusammenführen, aktualisieren, speichern, saveOrUpdate, persist Beispiel

Hibernate Session ist die Schnittstelle zwischen Java-Anwendung und Hibernate-Framework. Heute schauen wir uns die wichtigen Methoden von Session zum Speichern und Aktualisieren von Daten in Tabellen an: save, saveOrUpdate, persist, update und merge.

Hibernate Session

Beispiele zu Hibernate Session: zusammenführen, persist, speichern, saveOrUpdate.

Hibernate Session speichern

Wie der Methodenname schon sagt, kann hibernate save() verwendet werden, um eine Entität in der Datenbank zu speichern. Wir können diese Methode außerhalb einer Transaktion aufrufen, weshalb ich diese Methode zum Speichern von Daten nicht mag. Wenn wir sie ohne Transaktion verwenden und ein Kaskadeneffekt zwischen Entitäten besteht, wird nur die primäre Entität gespeichert, es sei denn, wir leeren die Sitzung. Zu Testzwecken haben wir zwei Entitätsbeans – Employee und 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 und Setter

	@Override
	public String toString() {
		return "Id= " + id + ", Name= " + name + ", Gehalt= " + salary
				+ ", {Adresse= " + 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
	@PrimaryKeyJoinColumn
	private Employee employee;

        // Getter und Setter

	@Override
	public String toString() {
		return "AdresseZeile1= " + addressLine1 + ", Stadt=" + city
				+ ", Postleitzahl=" + zipcode;
	}
}

Hier ist ein einfaches Hibernate-Programm, bei dem wir die save()-Methode in verschiedenen Fällen aufrufen.

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) {
		
		// Vorbereitungsarbeit
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		
		// Save-Beispiel - ohne Transaktion
		Session session = sessionFactory.openSession();
		Employee emp = getTestEmployee();
		long id = (Long) session.save(emp);
		System.out.println("1. Mitarbeiter speichern ohne Transaktion, id=" + id);
		session.flush(); // Adresse wird ohne diesen Schritt nicht gespeichert
		System.out.println("*****");
		
		// Save-Beispiel - mit Transaktion
		Transaction tx1 = session.beginTransaction();
		Session session1 = sessionFactory.openSession();
		Employee emp1 = getTestEmployee();
		long id1 = (Long) session1.save(emp1);
		System.out.println("2. Mitarbeiter speichern mit Transaktion, id=" + id1);
		System.out.println("3. Vor dem Abschluss der Speichertransaktion");
		tx1.commit();
		System.out.println("4. Nach dem Abschluss der Speichertransaktion");
		System.out.println("*****");
		
		// Save-Beispiel - bestehender Eintrag in der Tabelle
		Session session6 = sessionFactory.openSession();
		Transaction tx6 = session6.beginTransaction();
		Employee emp6 =  (Employee) session6.load(Employee.class, new Long(20));
		
		// Daten aktualisieren
		System.out.println("Mitarbeiterdetails=" + emp6);
		emp6.setName("Neuer Name");
		emp6.getAddress().setCity("Neue Stadt");
		
		long id6 = (Long) session6.save(emp6);
		emp6.setName("Neuer Name1"); // wird in der Datenbank aktualisiert
		System.out.println("5. Mitarbeiter speichern mit Transaktion, id=" + id6);
		System.out.println("6. Vor dem Abschluss der Speichertransaktion");
		tx6.commit();
		System.out.println("7. Nach dem Abschluss der Speichertransaktion");
		System.out.println("*****");
		
		// Ressourcen schließen
		sessionFactory.close();

	}

	public static Employee getTestEmployee() {
		Employee emp = new Employee();
		Address add = new Address();
		emp.setName("Test Mitarbeiter");
		emp.setSalary(1000);
		add.setAddressLine1("Test Adresse1");
		add.setCity("Test Stadt");
		add.setZipcode("12121");
		emp.setAddress(add);
		add.setEmployee(emp);
		return emp;
	}
}

Beim Ausführen des obigen Programms erhalten wir folgende Ausgabe:

Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
1. Mitarbeiter speichern ohne Transaktion, id=149
Hibernate: insert into ADDRESS (address_line1, city, zipcode, emp_id) values (?, ?, ?, ?)
*****
Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
2. Mitarbeiter speichern mit Transaktion, id=150
3. Vor dem Abschluss der Speichertransaktion
Hibernate: insert into ADDRESS (address_line1, city, zipcode, emp_id) values (?, ?, ?, ?)
4. Nach dem Abschluss der Speichertransaktion
*****
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=?
Mitarbeiterdetails=Id= 20, Name= Kumar1, Gehalt= 1000.0, {Adresse= AdresseZeile1= Test Adresse1, Stadt=Blr, Postleitzahl=12121}
5. Mitarbeiter speichern mit Transaktion, id=20
6. Vor dem Abschluss der Speichertransaktion
Hibernate: update EMPLOYEE set emp_name=?, emp_salary=? where emp_id=?
Hibernate: update ADDRESS set address_line1=?, city=?, zipcode=? where emp_id=?
7. Nach dem Abschluss der Speichertransaktion
*****

Einige wichtige Punkte, die wir aus der obigen Ausgabe bestätigen können:

  • Wir sollten speichern außerhalb des Transaktionsrahmens vermeiden, da sonst zugeordnete Entitäten nicht gespeichert werden, was zu Inkonsistenz der Daten führt. Es ist sehr leicht, das Leeren der Sitzung zu vergessen, da es keine Ausnahme oder Warnung auslöst.
  • Die Hibernate-Speichermethode gibt die generierte ID sofort zurück, da das primäre Objekt sofort gespeichert wird, wenn die Methode save aufgerufen wird.
  • Wenn es andere Objekte gibt, die vom primären Objekt abgeleitet sind, werden diese beim Abschluss der Transaktion oder beim Leeren der Sitzung gespeichert.
  • Für Objekte, die sich im persistenten Zustand befinden, aktualisiert save die Daten über eine Update-Abfrage. Dies geschieht, wenn die Transaktion abgeschlossen wird. Wenn es keine Änderungen am Objekt gibt, wird keine Abfrage ausgelöst.
  • Hibernate save lädt das Entitätsobjekt in den persistenten Kontext. Wenn Sie die Eigenschaften des Objekts nach dem Aufruf von save, aber vor Abschluss der Transaktion aktualisieren, wird es in die Datenbank gespeichert.

Hibernate Persist

Hibernate persist ist ähnlich wie save (mit Transaktion), und es fügt das Entitätsobjekt dem persistenten Kontext hinzu, sodass alle weiteren Änderungen verfolgt werden. Wenn die Eigenschaften des Objekts vor Abschluss der Transaktion oder vor dem Leeren der Sitzung geändert werden, wird es ebenfalls in die Datenbank gespeichert. Der zweite Unterschied besteht darin, dass wir die Methode persist() nur innerhalb des Transaktionsrahmens verwenden können, sodass sie sicher ist und sich um alle kaskadierten Objekte kümmert. Schließlich gibt persist nichts zurück, sodass wir das persistierte Objekt verwenden müssen, um den generierten Identifikationswert zu erhalten. Schauen wir uns ein einfaches Programm mit Hibernate persist an.

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) {
		
		// Vorbereitungsarbeit
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();	
		
		// persist Beispiel - mit Transaktion
		Session session2 = sessionFactory.openSession();
		Transaction tx2 = session2.beginTransaction();
		Employee emp2 = HibernateSaveExample.getTestEmployee();
		session2.persist(emp2);
		System.out.println("Persist aufgerufen");
		emp2.setName("Kumar"); // wird auch in der Datenbank aktualisiert
		System.out.println("Mitarbeitername aktualisiert");
		System.out.println("8. Persist aufgerufen mit Transaktion, id=" + emp2.getId() + ", address id=" + emp2.getAddress().getId());
		tx2.commit();
		System.out.println("*****");
		
		// Ressourcen schließen
		sessionFactory.close();

	}
}

Die Ausgabe des obigen Codes lautet:

Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
8. Persist aufgerufen mit Transaktion, 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=?
*****

Beachten Sie, dass das Mitarbeiterobjekt zuerst eingefügt wird und zum Zeitpunkt des Transaktionsabschlusses eine Update-Abfrage ausgeführt wird, um den Namenswert zu aktualisieren. Auch das zugeordnete Objekt Address wird in die Datenbank gespeichert.

Hibernate saveOrUpdate

Hibernate saveOrUpdate führt je nach bereitgestellten Daten zu Insert- oder Update-Abfragen. Wenn die Daten in der Datenbank vorhanden sind, wird eine Update-Abfrage ausgeführt. Wir können saveOrUpdate() auch ohne Transaktion verwenden, aber wiederum treten Probleme auf, wenn zugeordnete Objekte nicht gespeichert werden, falls die Sitzung nicht geleert wird. Hibernate saveOrUpdate fügt das Entitätsobjekt dem persistenten Kontext hinzu und verfolgt alle weiteren Änderungen. Diese Änderungen werden zum Zeitpunkt des Transaktionsabschlusses gespeichert, wie bei 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) {
		
		// Vorbereitungsarbeit
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		
		// saveOrUpdate Beispiel - ohne Transaktion
		Session session5 = sessionFactory.openSession();
		Employee emp5 = HibernateSaveExample.getTestEmployee();
		session5.saveOrUpdate(emp5);
		System.out.println("*****");
		
		// saveOrUpdate Beispiel - mit Transaktion
		Session session3 = sessionFactory.openSession();
		Transaction tx3 = session3.beginTransaction();
		Employee emp3 = HibernateSaveExample.getTestEmployee();
		session3.saveOrUpdate(emp3);
		emp3.setName("Kumar"); // wird in die DB gespeichert
		System.out.println("9. Vor Abschluss der saveOrUpdate Transaktion. Id=" + emp3.getId());
		tx3.commit();
		System.out.println("10. Nach Abschluss der saveOrUpdate Transaktion");
		System.out.println("*****");
		
		
		Transaction tx4 = session3.beginTransaction();
		emp3.setName("Aktualisierter Testname"); // Name geändert
		emp3.getAddress().setCity("Aktualisierte Stadt");
		session3.saveOrUpdate(emp3);
		emp3.setName("Kumar"); // erneut auf den vorherigen Wert geändert, daher kein Update
		System.out.println("11. Vor Abschluss der saveOrUpdate Transaktion. Id=" + emp3.getId());
		tx4.commit();
		System.out.println("12. Nach Abschluss der saveOrUpdate Transaktion");
		System.out.println("*****");

		// Ressourcen schließen
		sessionFactory.close();

	}
}

Das obige Programm erzeugt die folgende Ausgabe:

Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
*****
Hibernate: insert into EMPLOYEE (emp_name, emp_salary) values (?, ?)
9. Vor Abschluss der saveOrUpdate Transaktion. 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. Nach Abschluss der saveOrUpdate Transaktion
*****
11. Vor Abschluss der saveOrUpdate Transaktion. Id=166
Hibernate: update ADDRESS set address_line1=?, city=?, zipcode=? where emp_id=?
12. Nach Abschluss der saveOrUpdate Transaktion
*****

Beachten Sie, dass ohne Transaktion nur Employee gespeichert wird und Adressinformationen verloren gehen. Mit Transaktion wird das Employee-Objekt auf Änderungen überprüft, weshalb beim letzten Aufruf kein Update in der Employee-Tabelle erfolgt, obwohl der Wert zwischendurch geändert wurde; der Endwert bleibt gleich.

Hibernate Update

Hibernate update sollte verwendet werden, wenn wir sicher sind, dass wir nur die Entitätsinformationen aktualisieren. Diese Operation fügt das Entitätsobjekt dem persistenten Kontext hinzu, und weitere Änderungen werden verfolgt und gespeichert, wenn die Transaktion abgeschlossen wird. Schauen wir uns dieses Verhalten mit einem einfachen Programm an.

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) {

		// Vorbereitungsarbeit
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		Employee emp = (Employee) session.load(Employee.class, new Long(101));
		System.out.println("Mitarbeiterobjekt geladen. " + emp);
		tx.commit();

		// Update Beispiel
		emp.setName("Aktualisierter Name");
		emp.getAddress().setCity("Bangalore");
		Transaction tx7 = session.beginTransaction();
		session.update(emp);
		emp.setName("Endgültig aktualisierter Name");
		System.out.println("13. Vor Abschluss der Update Transaktion");
		tx7.commit();
		System.out.println("14. Nach Abschluss der Update Transaktion");

		// Ressourcen schließen
		sessionFactory.close();

	}
}

Beim ersten Ausführen des obigen Programms erhalten wir die folgende Ausgabe:

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=?
Mitarbeiterobjekt geladen. Id= 101, Name= Test Mitarbeiter, Gehalt= 1000.0, {Adresse= AdresseZeile1= Test Adresse1, Stadt=Test Stadt, Postleitzahl=12121}
13. Vor Abschluss der Update Transaktion
Hibernate: update EMPLOYEE set emp_name=?, emp_salary=? where emp_id=?
Hibernate: update ADDRESS set address_line1=?, city=?, zipcode=? where emp_id=?
14. Nach Abschluss der Update Transaktion

Beim weiteren Ausführen erhalten wir folgende Ausgabe:

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=?
Mitarbeiterobjekt geladen. Id= 101, Name= Endgültig aktualisierter Name, Gehalt= 1000.0, {Adresse= AdresseZeile1= Test Adresse1, Stadt=Bangalore, Postleitzahl=12121}
13. Vor Abschluss der Update Transaktion
14. Nach Abschluss der Update Transaktion

Beachten Sie, dass nach der ersten Ausführung keine Updates ausgelöst werden, da keine Werte aktualisiert wurden. Auch der Name des Mitarbeiters ist „Endgültig aktualisierter Name“, den wir nach dem Aufruf der Methode update() festgelegt haben. Dies bestätigt, dass Hibernate das Objekt auf Änderungen überprüft hat und dieser Wert zum Zeitpunkt des Abschlusses der Transaktion gespeichert wurde.

Hibernate Merge

Hibernate merge kann verwendet werden, um bestehende Werte zu aktualisieren. Diese Methode erstellt jedoch eine Kopie des übergebenen Entitätsobjekts und gibt sie zurück. Das zurückgegebene Objekt ist Teil des persistenten Kontexts und wird auf Änderungen überprüft, während das übergebene Objekt nicht überprüft wird. Dies ist der Hauptunterschied zwischen merge() und allen anderen Methoden. Schauen wir uns dies mit einem einfachen Programm an.

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) {

		// Vorbereitungsarbeit
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		Employee emp = (Employee) session.load(Employee.class, new Long(101));
		System.out.println("Mitarbeiterobjekt geladen. " + emp);
		tx.commit();

		// Merge Beispiel - Daten bereits in Tabellen vorhanden
		emp.setSalary(25000);
		Transaction tx8 = session.beginTransaction();
		Employee emp4 = (Employee) session.merge(emp);
		System.out.println(emp4 == emp); // gibt false zurück
		emp.setName("Test");
		emp4.setName("Kumar");
		System.out.println("15. Vor Abschluss der Merge-Transaktion");
		tx8.commit();
		System.out.println("16. Nach Abschluss der Merge-Transaktion");

		// Ressourcen schließen
		sessionFactory.close();

	}
}

Ausgabe bei der ersten Ausführung:

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=?
Mitarbeiterobjekt geladen. Id= 101, Name= Endgültig aktualisierter Name, Gehalt= 1000.0, {Adresse= AdresseZeile1= Test Adresse1, Stadt=Bangalore, Postleitzahl=12121}
false
15. Vor Abschluss der Merge-Transaktion
Hibernate: update EMPLOYEE set emp_name=?, emp_salary=? where emp_id=?
16. Nach Abschluss der Merge-Transaktion

Bei weiterer Ausführung lautet die Ausgabe:

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=?
Mitarbeiterobjekt geladen. Id= 101, Name= Kumar, Gehalt= 25000.0, {Adresse= AdresseZeile1= Test Adresse1, Stadt=Bangalore, Postleitzahl=12121}
false
15. Vor Abschluss der Merge-Transaktion
16. Nach Abschluss der Merge-Transaktion

Beachten Sie, dass das von merge() zurückgegebene Entitätsobjekt sich von dem übergebenen Objekt unterscheidet. Beachten Sie auch, dass bei weiterer Ausführung der Name „Kumar“ ist. Dies liegt daran, dass das zurückgegebene Objekt auf Änderungen überwacht wird. Das ist alles zu Hibernate Session Methoden wie save, update, saveOrUpdate, persist und merge. Ich hoffe, dass die obigen Beispiele helfen, eventuelle Zweifel zu klären.

Kostenlosen Account erstellen

Registrieren Sie sich jetzt und erhalten Sie Zugang zu unseren Cloud Produkten.

Das könnte Sie auch interessieren:

centron Managed Cloud Hosting in Deutschland

Java-Array: So prüfst du Werte effizient

JavaScript
Wie prüft man, ob ein Java Array einen Wert enthält? Es gibt viele Möglichkeiten, um zu überprüfen, ob ein Java Array einen bestimmten Wert enthält. Einfache Iteration mit einer for-Schleife…
centron Managed Cloud Hosting in Deutschland

Wie berechnet man den BLEU-Score in Python?

Python
Wie berechnet man den BLEU-Score in Python? Der BLEU-Score in Python ist eine Metrik, die die Güte von maschinellen Übersetzungsmodellen misst. Ursprünglich wurde er nur für Übersetzungsmodelle entwickelt, wird jedoch…