- Database vorbereiten
- Maven Project erstellen und die Bibliothek anmelden
- Die Klassen Entity
- Hibernate Konfiguration
- SessionFactory
- Hibernate Query Language (HQL)
- Hibernate die Daten abfragen
- Was sind Transient, Persistent und Detached ?
- Das Lebenskreis vom Hibernate (Hibernate Lifecycle)
- Die Manipulation von Insert, Update, Delete mit Hibernate
- Aus Entity Klassen die Tabelle erstellen
Die Anleitung zu Java Hibernate
1. Database vorbereiten
Hibernate ist ursprunglich eine Bibliothek, die zur Arbeit mit allen DB Typen geboren wird. Es ist unabhängig von einem DB Typ, das Sie gewählt haben. Wenn Java"Einmal schreiben, überall laufen" ist, ist Hibernatedann "Einmal schreiben, auf allen DB Typen laufen"
In diesem Artikel verwende ich simplehr, das eine einfache Database ist und in vielen Anleitungen in o7planning verwendet wird. Sie können es mit einer der Database Oracle, MySQL oder SQL Server erstellen. Sehen Sie die folgende Anleitung:
2. Maven Project erstellen und die Bibliothek anmelden
Hier erstelle ich ein Projekt Maven , und melde ich die Bibliothek Hibernate in pom.xml an.
- File/New/Other...
Project is created.
In pom.xml melde ich die Bibliothek Hibernate 5, und die Bibliothek JDBC für die unterschiedlichen Database Oracle, MySQL und SQL Server.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.o7planning</groupId>
<artifactId>HibernateTutorial</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>HibernateTutorial</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<!-- Repository for ORACLE JDBC Driver -->
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Hibernate Core -->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.2.Final</version>
</dependency>
<!-- MySQL JDBC driver -->
<!-- http://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<!-- Oracle JDBC driver -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
<!-- SQLServer JDBC driver (JTDS) -->
<!-- http://mvnrepository.com/artifact/net.sourceforge.jtds/jtds -->
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
</project>
3. Die Klassen Entity
Wir erstellen die Klassen Entity. Jeder Entity vertritt eine Tabelle in DB. Sagen wir die Dinge in dieser Klasse nicht.
- Department - Die Abteilung
- Employee - Der Mitarbeiter
- SalaryGrade -Lohn-Stufe
- Timekeeper - Der Zeitnehmer.
Department.java
package org.o7planning.tutorial.hibernate.entities;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@Table(name = "DEPARTMENT",
uniqueConstraints = { @UniqueConstraint(columnNames = { "DEPT_NO" }) })
public class Department {
private Integer deptId;
private String deptNo;
private String deptName;
private String location;
private Set<Employee> employees = new HashSet<Employee>(0);
public Department() {
}
public Department(Integer deptId, String deptName, String location) {
this.deptId = deptId;
this.deptNo = "D" + this.deptId;
this.deptName = deptName;
this.location = location;
}
@Id
@Column(name = "DEPT_ID")
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
@Column(name = "DEPT_NO", length = 20, nullable = false)
public String getDeptNo() {
return deptNo;
}
public void setDeptNo(String deptNo) {
this.deptNo = deptNo;
}
@Column(name = "DEPT_NAME", nullable = false)
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Column(name = "LOCATION")
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "department")
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
}
Employee.java
package org.o7planning.tutorial.hibernate.entities;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;
@Entity
@Table(name = "EMPLOYEE",
uniqueConstraints = { @UniqueConstraint(columnNames = { "EMP_NO" }) })
public class Employee {
private Long empId;
private String empNo;
private String empName;
private String job;
private Employee manager;
private Date hideDate;
private Float salary;
private byte[] image;
private Department department;
private Set<Employee> employees = new HashSet<Employee>(0);
public Employee() {
}
public Employee(Long empId, String empName, String job, Employee manager,
Date hideDate, Float salary, Float comm, Department department) {
this.empId = empId;
this.empNo = "E" + this.empId;
this.empName = empName;
this.job = job;
this.manager = manager;
this.hideDate = hideDate;
this.salary = salary;
this.department = department;
}
@Id
@Column(name = "EMP_ID")
public Long getEmpId() {
return empId;
}
public void setEmpId(Long empId) {
this.empId = empId;
}
@Column(name = "EMP_NO", length = 20, nullable = false)
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
@Column(name = "EMP_NAME", length = 50, nullable = false)
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
@Column(name = "JOB", length = 30, nullable = false)
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MNG_ID")
public Employee getManager() {
return manager;
}
public void setManager(Employee manager) {
this.manager = manager;
}
@Column(name = "HIRE_DATE", nullable = false)
@Temporal(TemporalType.DATE)
public Date getHideDate() {
return hideDate;
}
public void setHideDate(Date hideDate) {
this.hideDate = hideDate;
}
@Column(name = "SALARY", nullable = false)
public Float getSalary() {
return salary;
}
public void setSalary(Float salary) {
this.salary = salary;
}
@Column(name = "IMAGE", length = 1111111, nullable = true)
@Lob
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DEPT_ID", nullable = false)
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "empId")
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
}
SalaryGrade.java
package org.o7planning.tutorial.hibernate.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "SALARY_GRADE")
public class SalaryGrade {
private Integer grade;
private Float lowSalary;
private Float highSalary;
public SalaryGrade() {
}
public SalaryGrade(Integer grade, Float lowSalary, Float highSalary) {
this.grade = grade;
this.lowSalary = lowSalary;
this.highSalary = highSalary;
}
@Id
@Column(name = "GRADE")
public Integer getGrade() {
return grade;
}
public void setGrade(Integer grade) {
this.grade = grade;
}
@Column(name = "LOW_SALARY", nullable = false)
public Float getLowSalary() {
return lowSalary;
}
public void setLowSalary(Float lowSalary) {
this.lowSalary = lowSalary;
}
@Column(name = "HIGH_SALARY", nullable = false)
public Float getHighSalary() {
return highSalary;
}
public void setHighSalary(Float highSalary) {
this.highSalary = highSalary;
}
}
Timekeeper.java
package org.o7planning.tutorial.hibernate.entities;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "TIMEKEEPER")
public class Timekeeper {
public static final char IN = 'I';
public static final char OUT = 'O';
private String timekeeperId;
private Date dateTime;
private Employee employee;
// 'I' or 'O'
private char inOut;
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(name = "Timekeeper_Id", length = 36)
public String getTimekeeperId() {
return timekeeperId;
}
public void setTimekeeperId(String timekeeperId) {
this.timekeeperId = timekeeperId;
}
@Column(name = "Date_Time", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
public Date getDateTime() {
return dateTime;
}
public void setDateTime(Date dateTime) {
this.dateTime = dateTime;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "EMP_ID", nullable = false)
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
@Column(name = "In_Out", nullable = false, length = 1)
public char getInOut() {
return inOut;
}
public void setInOut(char inOut) {
this.inOut = inOut;
}
}
4. Hibernate Konfiguration
Das Zweck ist, dass Hibernate Database lesen kann sowie die Liste der Entity , die Sie in den vorherigen Schritt erstellt haben, anmelden
Die File hibernate.cfg.xml Konfiguration wird in src/main/java lokalisiert.
hibernate.cfg.xml (ORACLE)
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:db11g</property>
<property name="hibernate.connection.username">simplehr</property>
<property name="hibernate.connection.password">12345</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.connection.release_mode">auto</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.connection.autoReconnect">true</property>
<mapping class="org.o7planning.tutorial.hibernate.entities.Department" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Employee" />
<mapping class="org.o7planning.tutorial.hibernate.entities.SalaryGrade" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Timekeeper" />
</session-factory>
</hibernate-configuration>
hibernate.cfg.xml (MySQL)
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://tran-vmware:3306/simplehr?serverTimezone=UTC</property>
<property name="connection.username">root</property>
<property name="connection.password">1234</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping class="org.o7planning.tutorial.hibernate.entities.Department" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Employee" />
<mapping class="org.o7planning.tutorial.hibernate.entities.SalaryGrade" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Timekeeper" />
</session-factory>
</hibernate-configuration>
hibernate.cfg.xml (SQL Server)
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<property name="connection.url">jdbc:jtds:sqlserver://localhost:1433/simplehr;instance=SQLEXPRESS</property>
<property name="connection.username">sa</property>
<property name="connection.password">1234</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping class="org.o7planning.tutorial.hibernate.entities.Department" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Employee" />
<mapping class="org.o7planning.tutorial.hibernate.entities.SalaryGrade" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Timekeeper" />
</session-factory>
</hibernate-configuration>
Jede Database hat eine unterschiedliche Dialect
Zum Beispiel:
Dialect für Oracle:
- org.hibernate.dialect.Oracle10gDialect (Oracle 10g &11g)
- org.hibernate.dialect.Oracle12cDialect
Dialect für SQL Server:
- org.hibernate.dialect.SQLServerDialect
- org.hibernate.dialect.SQLServer2012Dialect
- org.hibernate.dialect.SQLServer2008Dialect
Dialect für MySQL:
- org.hibernate.dialect.MySQLDialect
- org.hibernate.dialect.MySQL5Dialect
Achtung: org.hibernate.dialect.Oracle10gDialect wird für Oracle 10g, 11g, 12c benutzt.
Was ist Dialect?
Dialect ist eine Klasse, die Hibernate sagt, wie die DatenTypen von Database zur die Datentypen vom Java und umgekehrt umzuwandeln. Gleichzeitig wird es benutzt um die Umwandlung zwischen die Funktionen von HSQL (Hibernate SQL) zur entsprechenden Funktionen von Database zu definieren.
Java SQL Type | Oracle | My SQL | SQL Server |
Types.BIT | number(1,0) | bit | bit |
Types.BIGINT | number(19,0) | bigint | bigint |
Types.DATE | date | date | date |
....... | |||
Types.CLOB | clob | longtext | varchar(MAX) |
Types.BLOB | blob | longblob | varbinary(MAX) |
5. SessionFactory
HibernateUtils ist eine Utility Klasse. Es hat ein Method für die Zurückgabe des Objekt SessionFactory. Die Klasse wird regelmäßig in die Beispiele verwendet.
HibernateUtils.java
package org.o7planning.tutorial.hibernate;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;
public class HibernateUtils {
private static final SessionFactory sessionFactory = buildSessionFactory();
// Hibernate 5:
private static SessionFactory buildSessionFactory() {
try {
// Create the ServiceRegistry from hibernate.cfg.xml
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()//
.configure("hibernate.cfg.xml").build();
// Create a metadata sources using the specified service registry.
Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build();
return metadata.getSessionFactoryBuilder().build();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}
6. Hibernate Query Language (HQL)
Hibernate benutzt die Sprache Hibernate Query Language (HQL) um die Daten abzufragen (query). HQL hat einen kleinen Unterschied mit SQL, das Sie kennen.
SQL:
- Die Daten auf die Tabelle abfragen (query)
HQL:
- die Daten auf die Klassen Entity abfragen (query).
-- SQL
-- This is a SQL query in table DEPARTMENT.
Select d.DEPT_NO, d.DEPT_NAME from DEPARTMENT d;
-- HQL
-- This is a HQL query in Entity Department.
Select d.deptNo, d.deptName from Department d;
-- Query Object
Select d from Department d;
The rules of operation of Hibernate:
Ihre Applikation, die die Commands HQL während Runtime von Hibernate schreibt, kennt, dass sie mit welchem Database-Typ arbeitet. Sie wird die Command HQL zu dem den DB-Typ entsprechenden SQL wechseln. In der Praxis kennen wir, dass die Syntax SQL den kleinen Unterschied zwischen die verschiedenen Database-Typen hat. Und so sind die Daten-Typen.
Sie können die Syntax HQL in ... referenzieren
7. Hibernate die Daten abfragen
Es gibt viele Maßnahmen um die Daten in Hibernate abzufragen. In diesem Part werde ich einige üblichen Maßnahme zum Daten-Abfragen vorstellen.
Die Objekt durch die Verwendung von HQL abfragen
Das ersten Beispiel: HQL verwenden, die Objekt Entity abzufragen
QueryObjectDemo.java
package org.o7planning.tutorial.hibernate.query;
import java.util.List;
import org.hibernate.query.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class QueryObjectDemo {
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
try {
// All the action with DB via Hibernate
// must be located in one transaction.
// Start Transaction.
session.getTransaction().begin();
// Create an HQL statement, query the object.
// Equivalent to the SQL statement:
// Select e.* from EMPLOYEE e order by e.EMP_NAME, e.EMP_NO
String sql = "Select e from " + Employee.class.getName() + " e "
+ " order by e.empName, e.empNo ";
// Create Query object.
Query<Employee> query = session.createQuery(sql);
// Execute query.
List<Employee> employees = query.getResultList();
for (Employee emp : employees) {
System.out.println("Emp: " + emp.getEmpNo() + " : "
+ emp.getEmpName());
}
// Commit data.
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// Rollback in case of an error occurred.
session.getTransaction().rollback();
}
}
}
Das Ergebnis von der Durchführung des Beispiel
Demo2:
QueryObjectDemo2.java
package org.o7planning.tutorial.hibernate.query;
import java.util.List;
import org.hibernate.query.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class QueryObjectDemo2 {
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
try {
// All the action with DB via Hibernate
// must be located in one transaction
// Start Transaction.
session.getTransaction().begin();
// Create an HQL statement, query the object.
// HQL with parameters.
// Equivalent to the SQL statement:
// Select e.* from EMPLOYEE e cross join DEPARTMENT d
// where e.DEPT_ID = d.DEPT_ID and d.DEPT_NO = :deptNo;
String sql = "Select e from " + Employee.class.getName() + " e "
+ " where e.department.deptNo=:deptNo ";
// Create query object.
Query<Employee> query = session.createQuery(sql);
query.setParameter("deptNo", "D10");
// Execute query.
List<Employee> employees = query.getResultList();
for (Employee emp : employees) {
System.out.println("Emp: " + emp.getEmpNo() + " : "
+ emp.getEmpName());
}
// Commit data
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// Rollback in case of an error occurred.
session.getTransaction().rollback();
}
}
}
Einige Säulen durch die Verwendung von HQL abfragen
QuerySomeColumnDemo.java
package org.o7planning.tutorial.hibernate.query;
import java.util.List;
import org.hibernate.query.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class QuerySomeColumnDemo {
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
try {
session.getTransaction().begin();
// Query some columns.
String sql = "Select e.empId, e.empNo, e.empName from "
+ Employee.class.getName() + " e ";
Query<Object[]> query = session.createQuery(sql);
// Execute Query.
// Get the array of Object
List<Object[]> datas = query.getResultList();
for (Object[] emp : datas) {
System.out.println("Emp Id: " + emp[0]);
System.out.println(" Emp No: " + emp[1]);
System.out.println(" Emp Name: " + emp[2]);
}
// Commit data.
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// Rollback in case of an error occurred.
session.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung des Beispiel:
Einige Säulen durch die Verwendung von HQL und JavaBean abfragen
Falls Sie die Daten in einigen Säulen auf einige Tabelle entnehmen brauchen, ist die Verwendung von Java beans die beste Maßnahme. Die Klasse Java bean hat einen constructor um die Werte ihrer Felder zu initialisieren. Constructor nimmt an HQL Abfragen teil.
ShortEmpInfo.java
package org.o7planning.tutorial.hibernate.beans;
public class ShortEmpInfo {
private Long empId;
private String empNo;
private String empName;
//
// Constructor have 3 parameters, will be used in the Hibernate Query.
//
public ShortEmpInfo(Long empId, String empNo, String empName) {
this.empId = empId;
this.empNo = empNo;
this.empName = empName;
}
public Long getEmpId() {
return empId;
}
public void setEmpId(Long empId) {
this.empId = empId;
}
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
}
ShortEmpInfoQueryDemo.java
package org.o7planning.tutorial.hibernate.query;
import java.util.List;
import org.hibernate.query.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.beans.ShortEmpInfo;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class ShortEmpInfoQueryDemo {
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
try {
session.getTransaction().begin();
// Using constructor of ShortEmpInfo
String sql = "Select new " + ShortEmpInfo.class.getName()
+ "(e.empId, e.empNo, e.empName)" + " from "
+ Employee.class.getName() + " e ";
Query<ShortEmpInfo> query = session.createQuery(sql);
// Execute query.
// Get a List of ShortEmpInfo
List<ShortEmpInfo> employees = query.getResultList();
for (ShortEmpInfo emp : employees) {
System.out.println("Emp: " + emp.getEmpNo() + " : "
+ emp.getEmpName());
}
// Commit data.
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// Rollback in case of an error occurred.
session.getTransaction().rollback();
}
}
}
Query wiederherstellt das einzige Ergebnis
UniqueResultDemo.java
package org.o7planning.tutorial.hibernate.query;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Department;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class UniqueResultDemo {
public static Department getDepartment(Session session, String deptNo) {
String sql = "Select d from " + Department.class.getName() + " d "//
+ " where d.deptNo= :deptNo ";
Query<Department> query = session.createQuery(sql);
query.setParameter("deptNo", deptNo);
return (Department) query.getSingleResult();
}
public static Employee getEmployee(Session session, Long empId) {
String sql = "Select e from " + Employee.class.getName() + " e "//
+ " where e.empId= :empId ";
Query<Employee> query = session.createQuery(sql);
query.setParameter("empId", empId);
return (Employee) query.getSingleResult();
}
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
try {
session.getTransaction().begin();
Department dept = getDepartment(session, "D10");
Set<Employee> emps = dept.getEmployees();
System.out.println("Dept Name: " + dept.getDeptName());
for (Employee emp : emps) {
System.out.println(" Emp name: " + emp.getEmpName());
}
Employee emp = getEmployee(session, 7839L);
System.out.println("Emp Name: " + emp.getEmpName());
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
8. Was sind Transient, Persistent und Detached ?
DataUtils.java
package org.o7planning.tutorial.hibernate;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.o7planning.tutorial.hibernate.entities.Department;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class DataUtils {
public static Department findDepartment(Session session, String deptNo) {
String sql = "Select d from " + Department.class.getName() + " d "//
+ " Where d.deptNo = :deptNo";
Query<Department> query = session.createQuery(sql);
query.setParameter("deptNo", deptNo);
return query.getSingleResult();
}
public static Long getMaxEmpId(Session session) {
String sql = "Select max(e.empId) from " + Employee.class.getName() + " e ";
Query<Number> query = session.createQuery(sql);
Number value = query.getSingleResult();
if (value == null) {
return 0L;
}
return value.longValue();
}
public static Employee findEmployee(Session session, String empNo) {
String sql = "Select e from " + Employee.class.getName() + " e "//
+ " Where e.empNo = :empNo";
Query<Employee> query = session.createQuery(sql);
query.setParameter("empNo", empNo);
return query.getSingleResult();
}
}
Das ist das einfache Beispiel für die Verwendung von Session.persist(Object) um ein Objekt Transient in DB einzusetzen. Der Begriff vom Objekt Transitent, Persistent, Detached wird in diesem Beispiel erklärt.
PersistDemo.java
package org.o7planning.tutorial.hibernate.demo;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Department;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class PersistDemo {
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
Department department = null;
Employee emp = null;
try {
session.getTransaction().begin();
Long maxEmpId = DataUtils.getMaxEmpId(session);
Long empId = maxEmpId + 1;
// Get Persistent object.
department = DataUtils.findDepartment(session, "D10");
// Create transient object
emp = new Employee();
emp.setEmpId(empId);
emp.setEmpNo("E" + empId);
emp.setEmpName("Name " + empId);
emp.setJob("Coder");
emp.setSalary(1000f);
emp.setManager(null);
emp.setHideDate(new Date());
emp.setDepartment(department);
// Using persist(..)
// Now 'emp' is managed by Hibernate.
// it has Persistent status.
// No action at this time with DB.
session.persist(emp);
// At this step the data is pushed to the DB.
// Execute Insert statement.
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
// After the session is closed (commit, rollback, close)
// Objects 'emp', 'dept' became the Detached objects.
// It is no longer in the control of the session.
System.out.println("Emp No: " + emp.getEmpNo());
}
}
Das Ergebnis vom Beispiel-Laufen
9. Das Lebenskreis vom Hibernate (Hibernate Lifecycle)
Die Klasse Session vom Hibernate hat die einigen wichtigen Methode. Sie werden in die Gruppen wie die folgenden Illustration geteilt.
Ein Objekt in Hibernate hat einen der vier Status:
- Transient (Vorläufig)
- Persistent (Beständig)
- Removed (Entfernt)
- Detached (Getrennt - im Vergeleich mit der momentan Session)
Wir erklären durch die folgenden Illustration diese Status
Transient:
Falls Sie ein Objekt java aus ein Entity neu erstellen, hat dieses Objekt den Status vonTransient. Hibernate kennt seinen Existenz nicht. Es wird durch Hibernate nicht kontrolliert.
Persistent
Falls Sie ein Objekt Entity durch die Methode von get, load, find, getSingleResult,.. wiederherstellen, haben Sie ein Objekt, das einem Rekord unter die Database entspricht. Das Objekt hat den Status vom Persistent. Es wird durch Hibernate kontrolliert.
Transient -> Persistent
Session ruft ein der Methode von save, saveOrUpdate, persist, merge , das das Objekt Transient zum Management von Hibernate schieben wird und das Objekt wechselt zum Status von Persistent. Es entspricht der Aktion von insert oder update in Database.
Persistent -> Detached
Das Objekt Session ruft das Method evict(..) oder clear() um die Objekte mit dem Status von Persistent aus dem Management von Hibernate auszuschließen. Jetzt haben diese Objekte den neuen Status von Detached (getrennt). Wenn es nicht wieder eingefügt wird(Re-Attached), wird es nach dem normalen Mechanimus durch Java Garbage Collector entfernt.
Detached -> Persistent
Die Verwendung von einer der Methode : update(..), saveOrUpdate(..), merge(..) wird ein Objekt mit dem Status vom Detached in dem Management von Hibernate setzen. Es ist äquivalent mit der Aktion update oder insert unter Database. Das Objekt wird zum Status von Persistent wechseln.
Persistent -> Removed
Das Objekt Session ruft das Method remove(..) oder delete(..) um ein Objekt (Rekord) zu löschen. Das Objekt Persistent wird zum Status Removed (entfernt) wechseln.
10. Die Manipulation von Insert, Update, Delete mit Hibernate
Persistent
PersistentDemo.java
package org.o7planning.tutorial.hibernate.demo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Department;
public class PersistentDemo {
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
Department department = null;
try {
session.getTransaction().begin();
System.out.println("- Finding Department deptNo = D10...");
// Persistent object.
department = DataUtils.findDepartment(session, "D10");
System.out.println("- First change Location");
// Changing something on Persistent object.
department.setLocation("Chicago " + System.currentTimeMillis());
System.out.println("- Location = " + department.getLocation());
System.out.println("- Calling flush...");
// Use session.flush () to actively push the changes to the DB.
// It works for all changed Persistent objects.
session.flush();
System.out.println("- Flush OK");
System.out.println("- Second change Location");
// Change something on Persistent object
department.setLocation("Chicago " + System.currentTimeMillis());
// Print out location
System.out.println("- Location = " + department.getLocation());
System.out.println("- Calling commit...");
// Commit
session.getTransaction().commit();
System.out.println("- Commit OK");
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
// Create the session after it had been closed earlier
// (Cause by commit or update)
session = factory.getCurrentSession();
try {
session.getTransaction().begin();
System.out.println("- Finding Department deptNo = D10...");
// Query lại Department D10.
department = DataUtils.findDepartment(session, "D10");
// Print out location
System.out.println("- D10 Location = " + department.getLocation());
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung des Beispiel
Transient --> Persistent : Die Überblick
Transient --> Persistent : Die Verwendung von persist(Object)
PersistTransientDemo.java
package org.o7planning.tutorial.hibernate.demo;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
import org.o7planning.tutorial.hibernate.entities.Timekeeper;
public class PersistTransientDemo {
private static DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
private static Timekeeper persist_Transient(Session session, Employee emp) {
// Note:
// Configuring of timekeeperId
// @GeneratedValue(generator = "uuid")
// @GenericGenerator(name = "uuid", strategy = "uuid2")
Timekeeper tk1 = new Timekeeper();
tk1.setEmployee(emp);
tk1.setInOut(Timekeeper.IN);
tk1.setDateTime(new Date());
// Now, 'tk1' is transient object
System.out.println("- tk1 Persistent? " + session.contains(tk1));
System.out.println("====== CALL persist(tk).... ===========");
// Hibernate assign value to Id of 'tk1'
// No action to DB.
session.persist(tk1);
System.out
.println("- tk1.getTimekeeperId() = " + tk1.getTimekeeperId());
// Now 'tk1' is Persistent object.
// But no action with DB.
// ==> true
System.out.println("- tk1 Persistent? " + session.contains(tk1));
System.out.println("- Call flush..");
// Flush data to DB.
// Hibernate execute insert statement.
session.flush();
String timekeeperId = tk1.getTimekeeperId();
System.out.println("- timekeeperId = " + timekeeperId);
System.out.println("- inOut = " + tk1.getInOut());
System.out.println("- dateTime = " + df.format(tk1.getDateTime()));
System.out.println();
return tk1;
}
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
Employee emp = null;
try {
session.getTransaction().begin();
emp = DataUtils.findEmployee(session, "E7499");
persist_Transient(session, emp);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung des Beispiel
Transient --> Persistent : save(Object) verwenden
SaveTransientDemo.java
package org.o7planning.tutorial.hibernate.demo;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
import org.o7planning.tutorial.hibernate.entities.Timekeeper;
public class SaveTransientDemo {
private static DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
private static Timekeeper persist_Transient(Session session, Employee emp) {
// See configuration of timekeeperId:
// @GeneratedValue(generator = "uuid")
// @GenericGenerator(name = "uuid", strategy = "uuid2")
// Create an Object, Transitent state.
Timekeeper tk2 = new Timekeeper();
tk2.setEmployee(emp);
tk2.setInOut(Timekeeper.IN);
tk2.setDateTime(new Date());
// Now 'tk3' are state Transient.
System.out.println("- tk2 Persistent? " + session.contains(tk2));
System.out.println("====== CALL save(tk).... ===========");
// save() very similar to persist()
// save() return ID, persist() return void.
// Hibernate assign ID value to 'tk2', no action with DB
// And return ID of 'tk2'.
Serializable id = session.save(tk2);
System.out.println("- id = " + id);
//
System.out
.println("- tk2.getTimekeeperId() = " + tk2.getTimekeeperId());
// Now, 'tk2' has Persistent state
// It has been managed in Session.
// ==> true
System.out.println("- tk2 Persistent? " + session.contains(tk2));
System.out.println("- Call flush..");
// To push data into the DB, call flush().
// If not call flush() data will be pushed to the DB when calling commit().
// Will execute insert statement.
session.flush();
String timekeeperId = tk2.getTimekeeperId();
System.out.println("- timekeeperId = " + timekeeperId);
System.out.println("- inOut = " + tk2.getInOut());
System.out.println("- dateTime = " + df.format(tk2.getDateTime()));
System.out.println();
return tk2;
}
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
Employee emp = null;
try {
session.getTransaction().begin();
emp = DataUtils.findEmployee(session, "E7499");
persist_Transient(session, emp);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung des Beispiel
Transient --> Persistent : saveOrUpdate(Object) verwenden
SaveOrUpdateTransientDemo.java
package org.o7planning.tutorial.hibernate.demo;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
import org.o7planning.tutorial.hibernate.entities.Timekeeper;
public class SaveOrUpdateTransientDemo {
private static DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
private static Timekeeper saveOrUpdate_Transient(Session session,
Employee emp) {
// See configuration of timekeeperId:
// @GeneratedValue(generator = "uuid")
// @GenericGenerator(name = "uuid", strategy = "uuid2")
// Create an Object, Transitent state.
Timekeeper tk3 = new Timekeeper();
tk3.setEmployee(emp);
tk3.setInOut(Timekeeper.IN);
tk3.setDateTime(new Date());
// Now 'tk3' are state Transient.
System.out.println("- tk3 Persistent? " + session.contains(tk3));
System.out.println("====== CALL saveOrUpdate(tk).... ===========");
// Here Hibernate checks, 'tk3' have ID or not (timekeeperId)
// If no, it will be assigned automatically
session.saveOrUpdate(tk3);
System.out
.println("- tk3.getTimekeeperId() = " + tk3.getTimekeeperId());
// Now 'tk3' has Persistent state
// It has been managed in Session.
// But no action insert, or update to DB.
// ==> true
System.out.println("- tk3 Persistent? " + session.contains(tk3));
System.out.println("- Call flush..");
// To push data into the DB, call flush().
// If not call flush() data will be pushed to the DB when calling commit().
// Now possible to Insert or Update DB. (!!!)
// Depending on the ID of 'tk3' exists in the DB or not
session.flush();
String timekeeperId = tk3.getTimekeeperId();
System.out.println("- timekeeperId = " + timekeeperId);
System.out.println("- inOut = " + tk3.getInOut());
System.out.println("- dateTime = " + df.format(tk3.getDateTime()));
System.out.println();
return tk3;
}
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
Employee emp = null;
try {
session.getTransaction().begin();
emp = DataUtils.findEmployee(session, "E7499");
saveOrUpdate_Transient(session, emp);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung des Beispiel
Transient --> Persistent :merge(Object) verwenden
MergeTransientDemo.java
package org.o7planning.tutorial.hibernate.demo;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
import org.o7planning.tutorial.hibernate.entities.Timekeeper;
public class MergeTransientDemo {
private static DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
private static Timekeeper saveOrUpdate_Transient(Session session,
Employee emp) {
// Note:
// Configuring of timekeeperId
// @GeneratedValue(generator = "uuid")
// @GenericGenerator(name = "uuid", strategy = "uuid2")
Timekeeper tk4 = new Timekeeper();
tk4.setEmployee(emp);
tk4.setInOut(Timekeeper.IN);
tk4.setDateTime(new Date());
// Now 'tk4' Transient status.
System.out.println("- tk4 Persistent? " + session.contains(tk4));
System.out.println("====== CALL merge(tk).... ===========");
// Hibernate2 has method saveOrUpdateCopy
// Hibernate3 change saveOrUpdateCopy to merge
// So there will be similarities between the two methods merge and copyOrUpdate
// Here Hibernate check tk4 has ID or not
// If not, Hibernate assign value to ID of tk4
// Return copy of tk4.
Timekeeper tk4Copy = (Timekeeper) session.merge(tk4);
System.out
.println("- tk4.getTimekeeperId() = " + tk4.getTimekeeperId());
// Now 'tk4' still Transient state.
// and 'tk4Copy' has Persistent status
// No action with DB (insert or update).
System.out.println("- tk4 Persistent? " + session.contains(tk4));
// 'tk4Copy' has Persistent status
// ==> true
System.out
.println("- tk4Copy Persistent? " + session.contains(tk4Copy));
System.out.println("- Call flush..");
// This time have Insert or Update to DB. (!!!)
session.flush();
// 'tk4' still Transitent, after flush().
// merge(..) safer than saveOrUpdate().
System.out.println("- tk4 Persistent? " + session.contains(tk4));
//
String timekeeperId = tk4.getTimekeeperId();
System.out.println("- timekeeperId = " + timekeeperId);
System.out.println("- inOut = " + tk4.getInOut());
System.out.println("- dateTime = " + df.format(tk4.getDateTime()));
System.out.println();
return tk4;
}
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
Employee emp = null;
try {
session.getTransaction().begin();
emp = DataUtils.findEmployee(session, "E7499");
saveOrUpdate_Transient(session, emp);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
Das Ergenis der Durchführung des Beispiel
Persistent --> Detached
Ein Objekt mit dem Status von Persistent (durch Hibernate managet) kann zum Status vom Detached (getrennt, durch Hibernate nicht managet) durch das folgende Method von Session:
- evict(Object)
Ein Objekt aus dem Management vom Hibernate auschließen
- clear()
Alle Objekte aus dem Management vom Hibernate ausschliessen
Achtung: Wenn das Objekt Session ein der Methode: commit(), close(), rollback() aufruft, wird die Session enden. Alle Objekte Persistence von dieser session werden als Detached für eine neue Session
EvictDemo.java
package org.o7planning.tutorial.hibernate.demo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class EvictDemo {
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
Employee emp = null;
try {
session.getTransaction().begin();
// This is object has Persistent status
emp = DataUtils.findEmployee(session, "E7499");
// ==> true
System.out.println("- emp Persistent? " + session.contains(emp));
// using evict() to evicts a single object from the session
session.evict(emp);
// Now 'emp' has Detached status
// ==> false
System.out.println("- emp Persistent? " + session.contains(emp));
// All change on the 'emp' will not update
// if not reatach 'emp' to session
emp.setEmpNo("NEW");
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung eines Beispiel
ClearDemo.java
package org.o7planning.tutorial.hibernate.demo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Department;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class ClearDemo {
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
Employee emp = null;
Department dept = null;
try {
session.getTransaction().begin();
// It is an object has Persistent status.
emp = DataUtils.findEmployee(session, "E7499");
dept = DataUtils.findDepartment(session, "D10");
// clear() evicts all the objects in the session.
session.clear();
// Now 'emp' & 'dept' has Detached status
// ==> false
System.out.println("- emp Persistent? " + session.contains(emp));
System.out.println("- dept Persistent? " + session.contains(dept));
// All change on the 'emp' will not update
// if not reatach 'emp' to session
emp.setEmpNo("NEW");
dept = DataUtils.findDepartment(session, "D20");
System.out.println("Dept Name = "+ dept.getDeptName());
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung eines Beispiel
Detached --> Persistent : Die Überblick
Ein Objekt mit dem Status vom Detached (aus dem Management von Hibernate getrennt) kann durch einige Methode von Session wieder eingefügt (Re-attach) werden.
- update(Object)
- saveOrUpdate(Object)
- merge(Object)
- refresh(Object)
- lock(Object)
Sie können in die folgenden Beispiele den Unterschied zwischen die Methode sehen.
Detached --> Persistent : update(Object) verwenden
UpdateDetachedDemo.java
package org.o7planning.tutorial.hibernate.demo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class UpdateDetachedDemo {
public static void main(String[] args) {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session1 = factory.getCurrentSession();
Employee emp = null;
try {
session1.getTransaction().begin();
// This is a Persistent object.
emp = DataUtils.findEmployee(session1, "E7499");
// session1 was closed after a commit is called.
session1.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session1.getTransaction().rollback();
}
// Open other session
Session session2 = factory.getCurrentSession();
try {
session2.getTransaction().begin();
// Check state of 'emp'
// ==> false
System.out.println("- emp Persistent? " + session2.contains(emp));
System.out.println("Emp salary: " + emp.getSalary());
emp.setSalary(emp.getSalary() + 100);
// update (..) is only used for Detached object.
// (Not for Transient object).
// Use the update (emp) to bring back emp Persistent state.
session2.update(emp);
// Call flush
// Update statement will be called.
session2.flush();
System.out.println("Emp salary after update: " + emp.getSalary());
// session2 was closed after a commit is called.
session2.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session2.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung des Beispiel
Detached --> Persistent : saveOrUpdate(Object) verwenden
SaveOrUpdateDetachedDemo.java
package org.o7planning.tutorial.hibernate.demo;
import java.util.Random;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class SaveOrUpdateDetachedDemo {
public static void main(String[] args) {
// An object Detached state.
Employee emp = getEmployee_Detached();
System.out.println(" - GET EMP " + emp.getEmpId());
// Random delete or not delete Employee
boolean delete = deleteOrNotDelete(emp.getEmpId());
System.out.println(" - DELETE? " + delete);
// Call saveOrUpdate for detached object.
saveOrUpdate_test(emp);
// After call saveOrUpdate()
System.out.println(" - EMP ID " + emp.getEmpId());
}
// Return Employee object has Detached state
private static Employee getEmployee_Detached() {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session1 = factory.getCurrentSession();
Employee emp = null;
try {
session1.getTransaction().begin();
Long maxEmpId = DataUtils.getMaxEmpId(session1);
System.out.println(" - Max Emp ID " + maxEmpId);
Employee emp2 = DataUtils.findEmployee(session1, "E7839");
Long empId = maxEmpId + 1;
emp = new Employee();
emp.setEmpId(empId);
emp.setEmpNo("E" + empId);
emp.setDepartment(emp2.getDepartment());
emp.setEmpName(emp2.getEmpName());
emp.setHideDate(emp2.getHideDate());
emp.setJob("Test");
emp.setSalary(1000F);
// emp has been managed by Hibernate
session1.persist(emp);
// session1 was closed after a commit is called.
// An Employee record are insert into DB.
session1.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session1.getTransaction().rollback();
}
// Session1 closed 'emp' switch to Detached state.
return emp;
}
// Random: delete or not delete.
private static boolean deleteOrNotDelete(Long empId) {
// A random number 0-9
int random = new Random().nextInt(10);
if (random < 5) {
return false;
}
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session2 = factory.getCurrentSession();
try {
session2.getTransaction().begin();
String sql = "Delete " + Employee.class.getName() + " e "
+ " where e.empId =:empId ";
Query query = session2.createQuery(sql);
query.setParameter("empId", empId);
query.executeUpdate();
session2.getTransaction().commit();
return true;
} catch (Exception e) {
e.printStackTrace();
session2.getTransaction().rollback();
return false;
}
}
private static void saveOrUpdate_test(Employee emp) {
SessionFactory factory = HibernateUtils.getSessionFactory();
// Open other session
Session session3 = factory.getCurrentSession();
try {
session3.getTransaction().begin();
// Check state of emp
// ==> false
System.out.println(" - emp Persistent? " + session3.contains(emp));
System.out.println(" - Emp salary before update: "
+ emp.getSalary());
// Set new salary for Detached emp object.
emp.setSalary(emp.getSalary() + 100);
// Using saveOrUpdate(emp) to switch emp to Persistent state
// Note: If exists object same ID in session, this method raise Exception
//
// Now, no action with DB.
session3.saveOrUpdate(emp);
// By pushing data into the DB.
// It will call a Insert or update statement.
// If the record is deleted before ==> insert
// Else ==> update.
session3.flush();
System.out
.println(" - Emp salary after update: " + emp.getSalary());
// session3 was closed after a commit is called.
session3.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session3.getTransaction().rollback();
}
}
}
Das Beispiel oben mehrmals durchführen, dann können Sie sehen, dass die zwei Situationen saveOrUpdatedie Aktionen : Insert oder Update in DB erstellen
INSERT:
UPDATE:
Detached --> Persistent : merge(Object) verwenden
Hibernate Version 2 hat das Method saveOrUpdateCopy(Object), ab die Version 3 umbenennet sie merge(Object). Deshalb hat mergedie Gemeinsamkeit und den kleinen Unterschied im Vergleich von saveOrUpdate.merge(Object) setzt das Objekt in das Management von Hibernate nicht aber es erstellt eine Kopie dieses Objekt und managet das Kopie-ObjektWenn Sie saveOrUpdate(aObject) auffrufen während bObject durch Hibernate managet wird und das gleiche ID mit aObject hat, wird eine Ausnahme geworfen. Bei der Verwendung von merge(aObject) wird diese Ausnahme nicht getroffen.
MergeDetachedDemo.java
package org.o7planning.tutorial.hibernate.demo;
import java.util.Random;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class MergeDetachedDemo {
public static void main(String[] args) {
// An object has Detached status
Employee emp = getEmployee_Detached();
System.out.println(" - GET EMP " + emp.getEmpId());
// Random: delete or not delete the Employee by ID.
boolean delete = deleteOrNotDelete(emp.getEmpId());
System.out.println(" - DELETE? " + delete);
// Call saveOrUpdate Detached object
saveOrUpdate_test(emp);
// After call saveOrUpdate
// ...
System.out.println(" - EMP ID " + emp.getEmpId());
}
// Method return Employee object
// and has Detached status.
private static Employee getEmployee_Detached() {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session1 = factory.getCurrentSession();
Employee emp = null;
try {
session1.getTransaction().begin();
Long maxEmpId = DataUtils.getMaxEmpId(session1);
System.out.println(" - Max Emp ID " + maxEmpId);
Employee emp2 = DataUtils.findEmployee(session1, "E7839");
Long empId = maxEmpId + 1;
emp = new Employee();
emp.setEmpId(empId);
emp.setEmpNo("E" + empId);
emp.setDepartment(emp2.getDepartment());
emp.setEmpName(emp2.getEmpName());
emp.setHideDate(emp2.getHideDate());
emp.setJob("Test");
emp.setSalary(1000F);
// 'emp' has Persistant state
session1.persist(emp);
// session1 was closed after a commit is called.
// An Employee record are insert into DB.
session1.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session1.getTransaction().rollback();
}
// session1 closed, 'emp' switched Detached state.
return emp;
}
// Delete Employee by ID
// Random: delete or not delete
private static boolean deleteOrNotDelete(Long empId) {
// A random number 0-9
int random = new Random().nextInt(10);
if (random < 5) {
return false;
}
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session2 = factory.getCurrentSession();
try {
session2.getTransaction().begin();
String sql = "Delete " + Employee.class.getName() + " e "
+ " where e.empId =:empId ";
Query query = session2.createQuery(sql);
query.setParameter("empId", empId);
query.executeUpdate();
session2.getTransaction().commit();
return true;
} catch (Exception e) {
e.printStackTrace();
session2.getTransaction().rollback();
return false;
}
}
private static void saveOrUpdate_test(Employee emp) {
SessionFactory factory = HibernateUtils.getSessionFactory();
// Open other session
Session session3 = factory.getCurrentSession();
try {
session3.getTransaction().begin();
// The fact, 'emp' has Detached state
// It is not managed by Hibernate.
// Check the status of emp:
// ==> false
System.out.println(" - emp Persistent? " + session3.contains(emp));
System.out.println(" - Emp salary before update: "
+ emp.getSalary());
// Set new salary for Detached object 'emp'
emp.setSalary(emp.getSalary() + 100);
// merge(emp) return empMerge, a copy of 'emp',
// empMerge managed by Hibernate
// 'emp' still in Detached state
//
// At this time there is no action regarding DB.
Employee empMerge = (Employee) session3.merge(emp);
// ==> false
System.out.println(" - emp Persistent? " + session3.contains(emp));
// ==> true
System.out.println(" - empMerge Persistent? "
+ session3.contains(empMerge));
// Push data into the DB.
// Here it is possible to create the Insert or Update on DB.
// If the corresponding record has been deleted by someone, it insert
// else it update
session3.flush();
System.out
.println(" - Emp salary after update: " + emp.getSalary());
// session3 closed after a commit is called.
session3.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session3.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung des Beispiel
INSERT:
UPDATE:
Detached --> Persistent : refresh(Object) verwenden
RefreshDetachedDemo.java
package org.o7planning.tutorial.hibernate.demo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.o7planning.tutorial.hibernate.DataUtils;
import org.o7planning.tutorial.hibernate.HibernateUtils;
import org.o7planning.tutorial.hibernate.entities.Employee;
public class RefreshDetachedDemo {
public static void main(String[] args) {
// an Object with Detached status
Employee emp = getEmployee_Detached();
System.out.println(" - GET EMP " + emp.getEmpId());
// Refresh Object
refresh_test(emp);
}
// Return Employee object has Detached state
private static Employee getEmployee_Detached() {
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session1 = factory.getCurrentSession();
Employee emp = null;
try {
session1.getTransaction().begin();
emp = DataUtils.findEmployee(session1, "E7839");
// session1 was closed after a commit is called.
// An Employee record are insert into DB.
session1.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session1.getTransaction().rollback();
}
// Session1 closed 'emp' switch to Detached state.
return emp;
}
private static void refresh_test(Employee emp) {
SessionFactory factory = HibernateUtils.getSessionFactory();
// Open other session
Session session2 = factory.getCurrentSession();
try {
session2.getTransaction().begin();
// Check the status of 'emp' (Detached)
// ==> false
System.out.println(" - emp Persistent? " + session2.contains(emp));
System.out.println(" - Emp salary before update: "
+ emp.getSalary());
// Set new salary for 'emp'.
emp.setSalary(emp.getSalary() + 100);
// refresh: make a query statement
// and switch 'emp' to Persistent state
// The changes are ignored
session2.refresh(emp);
// ==> true
System.out.println(" - emp Persistent? " + session2.contains(emp));
System.out.println(" - Emp salary after refresh: "
+ emp.getSalary());
session2.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session2.getTransaction().rollback();
}
}
}
Das Ergebnis der Durchführung des Beispiel
Detached --> Persistent : Using lock(Object)
- TODO...
No ADS