JPAのエンティティマネージャーとHibernateのエンティティマネージャー
JPA EntityManagerは、Java Persistence APIの中心に位置しています。Hibernateは、最も広く使われているJPAの実装です。
JPAエンティティマネージャ
- One of the most important aspect of a program is connection with database. Database connection and transaction with database is considered as most expensive transaction. ORM is a very important tool in this regard. ORM helps in representing relations of database in terms of java objects.
- ORM consists of two concepts object-oriented and relational programming.
- Hibernate is an ORM framework where programmer describes the way objects are represented in database. Hibernate handles the conversion automatically.
- Hibernate provides implementation of JPA interfaces EntityManagerFactory and EntityManager.
- EntityManagerFactory provides instances of EntityManager for connecting to same database. All the instances are configured to use the same setting as defined by the default implementation. Several entity manager factories can be prepared for connecting to different data stores.
- JPA EntityManager is used to access a database in a particular application. It is used to manage persistent entity instances, to find entities by their primary key identity, and to query over all entities.
JPAエンティティマネージャーメソッドを日本語で一つのオプションで言い換えてください。
JPA EntityManagerは、以下の一連のメソッドでサポートされています。読みやすさのために、メソッドの引数は省略しています。
-
- persist – Make an instance managed and persistent.
-
- merge – Merge the state of the given entity into the current persistence context.
-
- remove – Remove the entity instance.
-
- find – Find by primary key. Search for an entity of the specified class and primary key. If the entity instance is contained in the persistence context, it is returned from there.
-
- getReference – returns and instance which is lazily fetched and will throw EntityNotFoundException when the instance is accessed for the first time.
-
- flush – Synchronizes the persistence context with the database.
-
- setFlushMode – set the flush mode for all the objects of the persistence context.
-
- getFlushMode – get the flush mode for all the objects of the persistence context.
-
- lock – Lock an entity instance that is contained in the persistence context with the specified lock mode type.
-
- refresh – it refreshes the state of the instance from the database also it will overwrite the changes to the entity.
-
- clear – Clear the persistence context, causing all managed entities to become detached. Changes made to entities that have not been flushed to the database will not be persisted.
-
- detach – this is similar to the clear method, only addition is the entity which previously referenced the detached object will continue to do so.
-
- contains – it checks if the managed entity belongs to the current persistence context.
-
- getLockMode – get the current lock mode for entity instance.
-
- setProperty – set an entity manager property or hint.
-
- getProperties – get the properties and hints associated with the entity manager.
-
- createQuery – Create an instance of Query for executing a Java Persistence query language statement.
-
- createNamedQuery – Create an instance of Query for executing a Java Persistence named query language statement.
-
- createNativeQuery – Create an instance of Query for executing a native sql statement.
-
- createNamedStoredProcedureQuery – Create an instance of StoredProcedureQuery for executing a stored procedure in the database.
-
- createStoredProcedureQuery – Create an instance of StoredProcedureQuery for executing a stored procedure in the database.
-
- joinTransaction – Indicate to the entity manager that a JTA transaction is active. This method should be called on a JTA application managed entity manager that was created outside the scope of the active transaction to associate it with the current JTA transaction.
-
- isJoinedToTransaction – it determines if the entityManager is linked to the current transaction.
-
- unwrap – Return an object of the specified type to allow access to the provider-specific API
-
- getDelegate – return the provider object for the entityManager.
-
- close – close an application-managed entityManager.
-
- isOpen – determine if the entityManager is open.
-
- getTransaction – Return the resource-level EntityTransaction object.
-
- getEntityManagerFactory – provides the entity manager factory for the entity manager.
-
- getCriteriaBuilder – Return an instance of CriteriaBuilder for the creation of CriteriaQuery objects.
-
- getMetamodel – Return an instance of Metamodel interface for access to the metamodel of the persistence unit.
-
- createEntityGraph – Return a mutable EntityGraph that can be used to dynamically create an EntityGraph.
- getEntityGraph – returns a named entityGraph
エンティティマネージャの例プロジェクトを通じて、いくつかの方法を見てみましょう。
ヒベルネートのエンティティマネージャの例
CREATE TABLE `employee` (
`employee_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`employee_name` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`employee_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
私たちの例には非常にシンプルなテーブルですが、それは私たちがEntityManagerの使用を示すために最適です。
ヒバネイトのMaven依存関係
私たちはpom.xmlファイルにHibernateとMySQLのJavaドライバの依存関係を含める必要があります。私は最新のmysql-connector-javaのjarを使用してHibernate 5を利用しています。
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.scdev.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>hibernate-entitymanager</name>
<url>https://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- MySQL connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.5</version>
</dependency>
<!-- Hibernate 5.2.6 Final -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.6.Final</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Hibernateのpersistence.xml
Hibernateを使用する際に最も重要な部分は、persistence.xmlファイルを提供することです。このxmlファイルにはデータベースへの接続設定が保持されます。
<persistence xmlns="https://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/persistence
https://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="persistence">
<description>Hibernate Entity Manager Example</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/Test" />
<property name="javax.persistence.jdbc.user" value="scdev" />
<property name="javax.persistence.jdbc.password" value="scdev" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
- hibernate.show_sql is used to tell hibernate to print sql queries into log files or console.
- The most important configuration is provider class i.e. org.hibernate.jpa.HibernatePersistenceProvider. This is how Hibernate is hooked into our application to be used as JPA implementation.
- There are properties to connect to your database and driver to use.
- It is important to note that persistence.xml should be placed in the META-INF directory, as you can see from the project image.
ヒベルネイトエンティティビーン
私たちは今、データベースで作成された従業員テーブルに対応するEmployee.javaクラスを作成します。Employeeクラスは、@Entityアノテーションを使用して宣言されたエンティティです。
package com.scdev.jpa.hibernate.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "employee")
public class Employee {
private int employeeId;
private String name;
@Id
@Column(name = "employee_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
@Column(name = "employee_name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Employee [employeeId=" + employeeId + ", name=" + name + "]";
}
}
今は、私たちのメインプログラムを作成し、EntityManagerのメソッドを使用していくつかのクエリを実行する時間です。
package com.scdev.jpa.hibernate.main;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.scdev.jpa.hibernate.model.Employee;
public class App {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence");
EntityManager entityManager = entityManagerFactory.createEntityManager();
System.out.println("Starting Transaction");
entityManager.getTransaction().begin();
Employee employee = new Employee();
employee.setName("Pankaj");
System.out.println("Saving Employee to Database");
entityManager.persist(employee);
entityManager.getTransaction().commit();
System.out.println("Generated Employee ID = " + employee.getEmployeeId());
// get an object using primary key.
Employee emp = entityManager.find(Employee.class, employee.getEmployeeId());
System.out.println("got object " + emp.getName() + " " + emp.getEmployeeId());
// get all the objects from Employee table
@SuppressWarnings("unchecked")
List<Employee> listEmployee = entityManager.createQuery("SELECT e FROM Employee e").getResultList();
if (listEmployee == null) {
System.out.println("No employee found . ");
} else {
for (Employee empl : listEmployee) {
System.out.println("Employee name= " + empl.getName() + ", Employee id " + empl.getEmployeeId());
}
}
// remove and entity
entityManager.getTransaction().begin();
System.out.println("Deleting Employee with ID = " + emp.getEmployeeId());
entityManager.remove(emp);
entityManager.getTransaction().commit();
// close the entity manager
entityManager.close();
entityManagerFactory.close();
}
}
-
- Persistence.createEntityManagerFactoryは、persistence.xmlファイルで提供されたpersistence-unitを使用してEntityManagerFactoryインスタンスを提供します。
-
- entityManagerFactory.createEntityManager()は、私たちが使用するためのEntityManagerインスタンスを作成します。createEntityManager()メソッドを呼び出すたびに、新しいEntityManagerインスタンスが返されます。
-
- entityManager.getTransaction().begin()メソッドは、最初に現在の永続化コンテキストからトランザクションを取得し、begin()メソッドを使用してトランザクションを開始します。
-
- entityManager.persist(employee)は、データベースにemployeeオブジェクトを永続化するために使用されます。
-
- entityManager.getTransaction().commit()メソッドは、トランザクションを取得し、同じトランザクションをコミットするために使用されます。これにより、すべての変更がデータベースにコミットされます。
-
- entityManager.find()は、主キーを使用してデータベース内のエンティティを検索するために使用されます。
-
- カスタムクエリを書きたい場合は、entityManager.createQuery()メソッドを使用することができます。ここで重要なポイントは、createQuery()メソッドにはエンティティクラスに指定された名前があることです。実際のテーブル名ではありません。
-
- entityManager.remove()は、データベースからエンティティを削除する必要がある場合にのみ使用する必要があります。
- entityManager.close()は、エンティティマネージャを閉じるために使用されます。同様にentityManagerFactory.close()はEntityManagerFactoryを閉じるために使用されます。これらのリソースは使用が終わったらすぐに閉じる必要があります。
上記のプログラムの実行例から生成された出力は以下の通りです。
Starting Transaction
Saving Employee to Database
Hibernate: insert into employee (employee_name) values (?)
Generated Employee ID = 11
got object Pankaj 11
Dec 07, 2017 1:05:23 PM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select employee0_.employee_id as employee1_0_, employee0_.employee_name as employee2_0_ from employee employee0_
Employee name= Test, Employee id 5
Employee name= Pankaj, Employee id 6
Employee name= Pankaj, Employee id 11
Deleting Employee with ID = 11
Hibernate: delete from employee where employee_id=?
データベースに保存される際に従業員IDが生成され、それがオブジェクトにマッピングされることに注目してください。また、コンソールに表示されるSQLクエリにも注目してください。Hibernateはさらにログを生成しますが、可読性を保つため、ここでは省略しています。これがJPA EntityManagerとそのHibernate実装の例です。最終的なHibernate EntityManagerの例プロジェクトは以下のリンクからダウンロードできます。
「JPA Hibernate EntityManagerのサンプルプロジェクトをダウンロードする」
参照:APIドキュメント