[[HOME>http://www.trance.co.jp/]] > [[技術情報]] > [[Java>http://www.trance.co.jp/wiki/index.php?%B5%BB%BD%D1%BE%F0%CA%F3#xe479566]] > Java Persistence API
* Java Persistence API 1.0(JPA) [#p067abdd]
#contents
** Java Persistence APIとは [#ye590c98]
- Javaオブジェクトの永続化のためのAPI
以前はEJBの仕様に含まれていたものが、EJB3.0より切り離され、EJBコンテナ以外での使用が可能となった.
また、O/Rマッピング、アノテーションを使用することにより、以前のEJBのような複雑な仕組みではなく、よりPOJOとして開発できるようになった.
** 特徴 [#s2f8465e]
- ''アノテーションによるマッピング''
-- XML設定ファイル減
-- コード量減
- ''4つのエンティティ状態(ライフサイクル)''
|~状態|~説明|~Persistent Indentity|~Persistence Context|
|&color(blue){''new''};|Entityが生成された状態|持たない|結びつきなし|
|&color(blue){''managed''};|EntityがEntityManagerに管理されている状態|持つ|結びつきあり|
|&color(blue){''removed''};|Entityが削除予約となっている状態|持つ|結びつきあり|
|&color(blue){''detached''};|Entityがデータベースと関連がなくなった状態|持つ|結びつきなし|
** 実装プロダクト [#h478525f]
Java Persistence APIは仕様であるため、実装プロダクトがいくつか存在する.
- Hibernate
- TopLink
- OpenJPA
** 使用方法 - 準備 (実装プロダクト:Hibernate) [#hc112776]
今回は、実装プロダクトとして、「Hibernate」を使用する.
*** インストール [#zf7238d6]
- ''ダウンロード''
以下のサイトより、3つのパッケージをダウンロードする.
サイト:http://www.hibernate.org/
パッケージ (2007/09/13時点)
-- Hibernate Core 3.2.5.ga
-- Hibernate Annotations 3.3.0 GA
-- Hibernate EntityManager 3.3.1 GA
- ''クラスパスを通す''
それぞれのパッケージは多くのライブラリに依存しているため、必要なライブラリ全てクラスパスを通す.
必要であるかは、同封のドキュメントにて確認する.
今回は実行時に必要なライブラリのみパスを通す.
-- Hibernate Core 3.2.5.ga
--- jta.jar
--- commons-logging-1.0.4.jar
--- xml-apis.jar
--- asm-attrs.jar
--- dom4j-1.6.1.jar
--- antlr-2.7.6.jar
--- cglib-2.1.3.jar
--- asm.jar
--- jdbc2_0-stdext.jar
--- xerces-2.6.2.jar
--- jaxen-1.1-beta-7.jar
--- commons-collections-2.1.1.jar
--- javassist.jar
--- hibernate3.jar
-- Hibernate Annotations 3.3.0 GA
--- hibernate-annotations.jar
--- ejb3-persistence.jar
--- hibernate-commons-annotations.jar
-- Hibernate EntityManager 3.3.1 GA
--- hibernate-entitymanager.jar
--- hibernate-validator.jar
--- jboss-archive-browsing.jar
*** 設定ファイル - persistence.xml [#k3cbb4f0]
&color(blue){''persistence.xml''};と言うファイルを作成し、DB等の設定を定義する.
ファイルの配置場所は、クラスパスの通った「META-INF」配下に配備する.
META-INF/persistence.xml
以下のサンプルはDBにMySQLを使用した例.
|[DB_ID]|ユーザID|
|[DB_PASSWORD]|パスワード|
|[DB_IP]|DBのIP|
|[DB_PORT]|DBのポート|
|[DB_DBNAME]|使用するDB名|
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="jpa-sample" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>sample.entity.User</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLMyISAMDialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="[DB_ID]" />
<property name="hibernate.connection.password" value="[DB_PASSWORD]" />
<property name="hibernate.connection.url" value="jdbc:mysql://[DB_IP]:[DB_PORT]/[DB_DBNAME]" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.use_sql_comments" value="true" />
</properties>
</persistence-unit>
</persistence>
- ''解説''
-- &color(blue){''<class>''}; - ''EntityBeanクラスの定義''
パッケージ名を含むクラス名を定義することで、JPAで使用するEntityBeanとみなされる.
-- &color(blue){''<properties>''}; - ''JDBC接続情報の定義''
Hibernateの''<property>''タグのname属性値
|~<property>タグのname属性値|~説明|
|hibernate.dialect|使用するDBクラス|
|hibernate.connection.driver_class|DBドライバクラス|
|hibernate.connection.username|ユーザ名|
|hibernate.connection.password|パスワード|
|hibernate.connection.url|DBのURL|
|hibernate.hbm2ddl.auto|自動的にDDLを有効にしデータベース出力する&br;validate:&br;update:&br;create:&br;create-drop:|
|hibernate.show_sql|ログにSQLを表示するか&br;true:表示する&br;false:表示しない|
|hibernate.format_sql|ログに表示したSQLをフォーマットするか&br;true:フォーマットする&br;false:フォーマットしない|
|hibernate.use_sql_comments|SQLコメントを表示するか&br;true:表示する&br;false:表示しない|
** 使用方法 - 実装 (単独テーブルへの追加、変更、削除、参照)[#ycd1e543]
以下のテーブルを操作するサンプルを作成する.
''テーブル名:User''
|~フィールド|~種別|~主キー|
|id|varchar(255)|●|
|age|int(11)||
|name|varchar(255)||
*** Entity Bean [#x982fa42]
EntityBeanを作成する.
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="User")
public class User implements Serializable {
@Id
@Column(name="id")
private String id;
@Column(name="name")
private String name;
@Column(name="age")
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- ''解説''
ユーザ情報を保持するためのユーザクラス(POJO)を作成し、以下のアノテーションを定義することで、EntityBeanとなる.
-- &color(blue){''@Entity''}; - ''Entity Beanであることを定義''
クラス定義の前に「@Entity」を記述し、「Entity Bean」であることを定義する.
-- &color(blue){''@Table(name="User")''}; - ''このEntity Beanとマッピングするテーブル名を定義''
クラス定義の前に「@Table(name="User")」を記述し、name要素にマッピングするテーブル名記述する.
クラス名テーブル名が同じ場合は、&color(red){「@Table(name="User")」は省略できる.};
-- &color(blue){''@Id''}; - ''Primary Keyを定義''
「Primary Key」となるインスタンス変数に定義する.
-- &color(blue){''@Column(name="id")''}; - ''このインスタンス変数とマッピングするカラム名を定義''
インスタンス変数定義の前に「@Column(name="id")」を記述し、name要素にマッピングするカラム名を記述する.
インスタンス変数名とカラム名が同じ場合は、&color(red){「@Column(name="id")」は省略できる.};
*** EntityManager [#t9605dc6]
EntityManagerは、Entity Beanの永続性を管理するためのオブジェクト.
EntityManagerは以下のようにして取得する.
// 永続化
EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-sample");
EntityManager entityManager = factory.createEntityManager();
- ''解説''
-- &color(blue){''Persistence.createEntityManagerFactory("jpa-sample");''}; - ''EntityManagerFactoryを取得''
Persistence#createEntityManagerFactory()を使用し、EntityManagerFactoryを取得する.
引数に、設定ファイル「persistence.xml」で記述した「persistence-unit name="jpa-sample"」の「jpa-sample」を渡す.
*** hibernate.hbm2ddl.autoによるDDL [#uae57a3f]
create table User (
id varchar(255) not null,
age integer not null,
name varchar(255),
primary key (id)
) type=MyISAM
*** サンプル [#s31d4867]
データベースへの、新規追加(Insert)、更新(Update)、削除(Delete)、参照(find)のサンプル(Junit4.4).
設定ファイル(persistence.xml)は、上記の設定とする.
package sample;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.junit.Test;
import sample.entity.User;
public class JpaHibernateTest {
private static final String PERSISTENCE_UNIT_NAME = "jpa-sample1";
/**
* 新規追加(Insert)
*/
@Test
public void insert() {
// 永続化
// ------------------------------
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager entityManager = factory.createEntityManager();
// データの追加
// ************************************
// EntityBeanをnew
// ライフサイクル:new
// ------------------------------
User user = new User();
user.setId("1");
user.setName("Insert");
user.setAge(10);
// Insert
// ライフサイクル:managed
// ------------------------------
entityManager.getTransaction().begin();
entityManager.persist(user);
entityManager.getTransaction().commit();
// 管理していたEntityBeanをクリア
// ライフサイクル:detached
// ------------------------------
entityManager.clear();
// 確認
// ************************************
User actual = entityManager.find(User.class, "1");
assertThat(actual.getId(), is("1"));
assertThat(actual.getName(), is("Insert"));
assertThat(actual.getAge(), is(10));
}
/**
* 更新(Update)
*/
@Test
public void update() {
// 永続化
// ------------------------------
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager entityManager = factory.createEntityManager();
// データの追加
// ************************************
// EntityBeanをnew
// ライフサイクル:new
// ------------------------------
User user = new User();
user.setId("1");
user.setName("Insert");
user.setAge(10);
// Insert
// ライフサイクル:managed
// ------------------------------
entityManager.getTransaction().begin();
entityManager.persist(user);
entityManager.getTransaction().commit();
// 管理していたEntityBeanをクリア
// ライフサイクル:detached
// ------------------------------
entityManager.clear();
// データの更新
// ************************************
// Select
// ライフサイクル:managed
// ------------------------------
User user2 = entityManager.find(User.class, "1");
user2.setName("Update");
// Update
// ライフサイクル:managed
// ------------------------------
entityManager.getTransaction().begin();
entityManager.merge(user2);
entityManager.getTransaction().commit();
// 管理していたEntityBeanをクリア
// ライフサイクル:detached
// ------------------------------
entityManager.clear();
// 確認
// ************************************
User actual = entityManager.find(User.class, "1");
assertThat(actual.getName(), is("Update"));
}
/**
* 削除(Delete)
*/
@Test
public void delete() {
// 永続化
// ------------------------------
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager entityManager = factory.createEntityManager();
// データの追加
// ************************************
// EntityBeanをnew
// ライフサイクル:new
// ------------------------------
User user = new User();
user.setId("1");
user.setName("Insert");
user.setAge(10);
// Insert
// ライフサイクル:managed
// ------------------------------
entityManager.getTransaction().begin();
entityManager.persist(user);
entityManager.getTransaction().commit();
// 管理していたEntityBeanをクリア
// ライフサイクル:detached
// ------------------------------
entityManager.clear();
// データの削除
// ************************************
// Select
// ライフサイクル:managed
// ------------------------------
User user2 = entityManager.find(User.class, "1");
// Delete
// ライフサイクル:removed
// ------------------------------
entityManager.getTransaction().begin();
entityManager.remove(user2);
entityManager.getTransaction().commit();
// 管理していたEntityBeanをクリア
// ライフサイクル:detached
// ------------------------------
entityManager.clear();
// 確認
// ************************************
User actual = entityManager.find(User.class, "1");
assertThat(actual, nullValue());
}
/**
* 主キーによる参照(Select)
*/
@Test
public void selectByPk() {
// 永続化
// ------------------------------
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager entityManager = factory.createEntityManager();
// データの追加
// ************************************
// EntityBeanをnew
// ライフサイクル:new
// ------------------------------
User user = new User();
user.setId("1");
user.setName("Insert");
user.setAge(10);
// Insert
// ライフサイクル:managed
// ------------------------------
entityManager.getTransaction().begin();
entityManager.persist(user);
entityManager.getTransaction().commit();
// 管理していたEntityBeanをクリア
// ライフサイクル:detached
// ------------------------------
entityManager.clear();
// Select
// ライフサイクル:managed
// ------------------------------
User actual = entityManager.find(User.class, "1");
// 確認
// ************************************
assertThat(actual.getId(), is("1"));
assertThat(actual.getName(), is("Insert"));
assertThat(actual.getAge(), is(10));
}
}
- ''解説''
-- &color(blue){''新規追加(Insert)''}; - ''EntityManager#persist(Object[EntityBean]));''
+++ Entityオブジェクトを生成する
ライフサイクル -> ''new''
User user = new User();
+++ Entityオブジェクトに追加する値をセットする
user.setId("1");
user.setName("Insert");
user.setAge(10);
+++ トランザクションを開始する
entityManager.getTransaction().begin();
+++ Entityオブジェクトを永続化する
ライフサイクル -> ''managed''
entityManager.persist(user);
+++ コミットする
entityManager.getTransaction().commit();
--- 発行されるSQL
insert
into
User
(age, name, id)
values
(?, ?, ?)
-- &color(blue){''更新(Update)''}; - ''EntityManager#merge(Object[EntityBean]);''
+++ 更新するEntityオブジェクトを取得する.
ライフサイクル -> ''managed''
User user2 = entityManager.find(User.class, "1");
+++ Entityオブジェクトに更新する値をセットする
user2.setName("Update");
+++ トランザクションを開始する
entityManager.getTransaction().begin();
+++ 永続化しているEntityオブジェクトとマージする
ライフサイクル -> ''managed''
entityManager.merge(user2);
+++ コミットする
entityManager.getTransaction().commit();
--- 発行されるSQL
update
User
set
age=?,
name=?
where
id=?
-- &color(blue){''削除(Delete)''}; - ''EntityManager#remove(Object[EntityBean]);''
+++ 削除するEntityオブジェクトを取得する
ライフサイクル -> ''managed''
User user2 = entityManager.find(User.class, "1");
+++ トランザクションを開始する
entityManager.getTransaction().begin();
+++ Entityオブジェクトを削除する
ライフサイクル -> ''remove''
entityManager.remove(user2);
+++ コミットする
entityManager.getTransaction().commit();
--- 発行されるSQL
delete
from
User
where
id=?
-- &color(blue){''主キーによる参照(Select)''}; - ''EntityManager#find(EntityClass, String[primary key]);''
+++ 主キーを指定して、Entityオブジェクトを取得する
ライフサイクル -> ''managed''
User user2 = entityManager.find(User.class, "1");
--- 発行されるSQL
select
user0_.id as id0_0_,
user0_.age as age0_0_,
user0_.name as name0_0_
from
User user0_
where
user0_.id=?
- ''まとめ''
-- &color(blue){''DBアクセス''};
|Insert|EntityManager#persist(Object[EntityBean]));|
|Update|EntityManager#merge(Object[EntityBean]);|
|Delete|EntityManager#remove(Object[EntityBean]);|
|Select (Primary Key)|EntityManager#find(EntityClass, String[primary key]);|
-- &color(blue){''トランザクション''};
|トランザクション開始|EntityManager#getTransaction()#begin();|
|コミット|EntityManager#getTransaction()#commit();|
|ロールバック|EntityManager#getTransaction()#rollback();|
*** サンプルダウンロード [#ffb1d2a1]
- [[jpa_hibernate-sample.zip[6.4MB]>http://www.trance.co.jp/wiki/index.php?down=jpa_hibernate-sample.zip]]
** 使用方法 - 実装 (1対多、多対1) [#md02552e]
以下のテーブルを操作するサンプルを作成する.
''テーブル名:OrderInfo''
|~フィールド|~種別|~主キー|
|id|int(11)|●|
|date|datetime||
''テーブル名:OrderInfoDetail''
|~フィールド|~種別|~主キー|
|id|int(11)|●|
|productName|varchar(255)||
|productPrice|int(11)||
|quantity|int(11)||
|orderInfo_id|int(11)||
*** Entity Bean [#q2d3ac2c]
「@Table」と「@Column」アノテーションは省略するため、
クラスメイトテーブル名、インスタンス変数名とカラムを同一にする.
package sample2.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class OrderInfo implements Serializable {
@Id
private int id;
private Date date;
@OneToMany(mappedBy="orderInfo")
private List<OrderInfoDetail> orderDetailList;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<OrderInfoDetail> getOrderDetailList() {
return orderDetailList;
}
public void setOrderDetailList(List<OrderInfoDetail> orderDetailList) {
this.orderDetailList = orderDetailList;
}
}
- ''解説''
-- &color(blue){''@OneToMany''}; - ''1対多のリレーションであることを定義''
インスタンス変数の前に「@OneToMany(mappedBy="orderInfo")」を記述し、mappedBy要素には、リレーション対象のクラスに定義したインスタンス変数名を記述する.
下記、「OrderInfoDetail」クラスの保持するOrderInfoオブジェクトのインスタンス変数「orderInfo」.
package sample2.entity;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
public class OrderInfoDetail implements Serializable {
@Id
private int id;
private String productName;
private int productPrice;
private int quantity;
@ManyToOne
private OrderInfo orderInfo;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public OrderInfo getOrderInfo() {
return orderInfo;
}
public void setOrderInfo(OrderInfo orderInfo) {
this.orderInfo = orderInfo;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public int getProductPrice() {
return productPrice;
}
public void setProductPrice(int productPrice) {
this.productPrice = productPrice;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
- ''解説''
-- &color(blue){''@ManyToOne''}; - ''多対1のリレーションであることを定義''
インスタンス変数の前に「@ManyToOne」を記述する.
*** persistence.xml [#oda9de4f]
上記persistence.xmlに以下を追記
<persistence-unit name="jpa-sample2" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>sample2.entity.OrderInfo</class>
<class>sample2.entity.OrderInfoDetail</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLMyISAMDialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="taadmin" />
<property name="hibernate.connection.password" value="trance" />
<property name="hibernate.connection.url" value="jdbc:mysql://192.168.3.150:3306/jpasample2" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.use_sql_comments" value="false" />
</properties>
</persistence-unit>
*** hibernate.hbm2ddl.autoによるDDL [#u3da96f4]
create table OrderInfo (
id integer not null,
date datetime,
primary key (id)
) type=MyISAM
create table OrderInfoDetail (
id integer not null,
productName varchar(255),
productPrice integer not null,
quantity integer not null,
orderInfo_id integer,
primary key (id)
) type=MyISAM
alter table OrderInfoDetail
add index FKFD49806D9973955 (orderInfo_id),
add constraint FKFD49806D9973955
foreign key (orderInfo_id)
references OrderInfo (id)
*** サンプル [#a75f0069]
package sample2;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.junit.Test;
import sample2.entity.OrderInfo;
import sample2.entity.OrderInfoDetail;
public class JpaHibernateTest2 {
private static final String PERSISTENCE_UNIT_NAME = "jpa-sample2";
@Test
public void oneToMany() {
// 永続化
// ------------------------------
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager entityManager = factory.createEntityManager();
// データの追加
// ************************************
// EntityBeanをnew
// ライフサイクル:new
// ------------------------------
Date InsertDate = new Date();
OrderInfo order = new OrderInfo();
order.setId(1);
order.setDate(InsertDate);
OrderInfoDetail detail1 = new OrderInfoDetail();
detail1.setId(1);
detail1.setOrderInfo(order);
detail1.setProductName("商品名1");
detail1.setProductPrice(1000);
detail1.setQuantity(1);
OrderInfoDetail detail2 = new OrderInfoDetail();
detail2.setId(2);
detail2.setOrderInfo(order);
detail2.setProductName("商品名2");
detail2.setProductPrice(2000);
detail2.setQuantity(2);
// Insert
// ライフサイクル:managed
// ------------------------------
entityManager.getTransaction().begin();
entityManager.persist(order);
entityManager.persist(detail1);
entityManager.persist(detail2);
entityManager.getTransaction().commit();
// 管理していたEntityBeanをクリア
// ライフサイクル:detached
// ------------------------------
entityManager.clear();
// Select
// ライフサイクル:managed
// ------------------------------
OrderInfo actual = entityManager.find(OrderInfo.class, 1);
// 確認
// ************************************
assertThat(actual.getId(), is(1));
List<OrderInfoDetail> orderDetailList = actual.getOrderDetailList();
assertThat(orderDetailList.size(), is(2));
OrderInfoDetail actualDetail1 = orderDetailList.get(0);
assertThat(actualDetail1.getId(), is(detail1.getId()));
assertThat(actualDetail1.getProductName(), is(detail1.getProductName()));
assertThat(actualDetail1.getProductPrice(), is(detail1.getProductPrice()));
assertThat(actualDetail1.getQuantity(), is(detail1.getQuantity()));
OrderInfoDetail actualDetail2 = orderDetailList.get(1);
assertThat(actualDetail2.getId(), is(detail2.getId()));
assertThat(actualDetail2.getProductName(), is(detail2.getProductName()));
assertThat(actualDetail2.getProductPrice(), is(detail2.getProductPrice()));
assertThat(actualDetail2.getQuantity(), is(detail2.getQuantity()));
}
@Test
public void ManyToOne() {
// 永続化
// ------------------------------
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager entityManager = factory.createEntityManager();
// データの追加
// ************************************
// EntityBeanをnew
// ライフサイクル:new
// ------------------------------
Date InsertDate = new Date();
OrderInfo order = new OrderInfo();
order.setId(1);
order.setDate(InsertDate);
OrderInfoDetail detail1 = new OrderInfoDetail();
detail1.setId(1);
detail1.setOrderInfo(order);
detail1.setProductName("商品名1");
detail1.setProductPrice(1000);
detail1.setQuantity(1);
OrderInfoDetail detail2 = new OrderInfoDetail();
detail2.setId(2);
detail2.setOrderInfo(order);
detail2.setProductName("商品名2");
detail2.setProductPrice(2000);
detail2.setQuantity(2);
// Insert
// ライフサイクル:managed
// ------------------------------
entityManager.getTransaction().begin();
entityManager.persist(order);
entityManager.persist(detail1);
entityManager.persist(detail2);
entityManager.getTransaction().commit();
// 管理していたEntityBeanをクリア
// ライフサイクル:detached
// ------------------------------
entityManager.clear();
// Select
// ライフサイクル:managed
// ------------------------------
OrderInfoDetail actual = entityManager.find(OrderInfoDetail.class, 1);
// 確認
// ************************************
assertThat(actual.getId(), is(detail1.getId()));
assertThat(actual.getProductName(), is(detail1.getProductName()));
assertThat(actual.getProductPrice(), is(detail1.getProductPrice()));
assertThat(actual.getQuantity(), is(detail1.getQuantity()));
OrderInfo actualOrder = actual.getOrderInfo();
assertThat(actualOrder.getId(), is(order.getId()));
}
}
- ''データ''
OrderInfo
|~id|~date|
|1|2007-09-26 10:23:33|
OrderInfoDetail
|~id|~productName|~productPrice|~quantity|~orderInfo_id|
|1|商品名1|1000|1|1|
|2|商品名2|2000|2|1|
- ''解説''
-- &color(blue){''1対多''};
+++ OrderInfoを取得する
OrderInfo actual = entityManager.find(OrderInfo.class, 1);
取得したOrderInfoのインスタンス変数「orderDetailList」には、リレーションで紐付けられているOrderInfoDetailオブジェクトが格納されている.
紐付けられているOrderInfoDetailは、「orderInfo_id」の値が「1」のOrderInfoDetail.
--- 発行されるSQL
select
orderinfo0_.id as id0_0_,
orderinfo0_.date as date0_0_
from
OrderInfo orderinfo0_
where
orderinfo0_.id=?
&BR;
select
orderdetai0_.orderInfo_id as orderInfo5_1_,
orderdetai0_.id as id1_,
orderdetai0_.id as id1_0_,
orderdetai0_.orderInfo_id as orderInfo5_1_0_,
orderdetai0_.productName as productN2_1_0_,
orderdetai0_.productPrice as productP3_1_0_,
orderdetai0_.quantity as quantity1_0_
from
OrderInfoDetail orderdetai0_
where
orderdetai0_.orderInfo_id=?
--- 結果
OrderInfo
:id->1
:date->2007-09-26 10:23:33
:orderDetailList->
OrderInfoDetail
:id->1
:productName->商品名1
:productPrice->1000
:quantity->1
:orderInfo_id->OrderInfo
OrderInfoDetail
:id->2
:productName->商品名2
:productPrice->2000
:quantity->2
:orderInfo_id->OrderInfo
-- &color(blue){''多対1''};
+++ OrderInfoDetailを取得する
OrderInfoDetail actual = entityManager.find(OrderInfoDetail.class, 1);
取得したOrderInfoDetailのインスタンス変数「orderInfo」には、リレーションで紐付けられているOrderInfoオブジェクトが格納されている.
紐付けられているOrderInfoは、「id」の値が「1」のOrderInfo.
--- 発行されるSQL
select
orderinfod0_.id as id1_1_,
orderinfod0_.orderInfo_id as orderInfo5_1_1_,
orderinfod0_.productName as productN2_1_1_,
orderinfod0_.productPrice as productP3_1_1_,
orderinfod0_.quantity as quantity1_1_,
orderinfo1_.id as id0_0_,
orderinfo1_.date as date0_0_
from
OrderInfoDetail orderinfod0_
left outer join
OrderInfo orderinfo1_
on orderinfod0_.orderInfo_id=orderinfo1_.id
where
orderinfod0_.id=?
--- 結果
OrderInfoDetail
:id->1
:productName->商品名1
:productPrice->1000
:quantity->1
:orderInfo_id->
OrderInfo
:id->1
:date->2007-09-26 10:23:33
:orderDetailList->OrderInfoDetail
*** サンプルダウンロード [#x493789f]
- [[jpa_hibernate-sample2.zip[6.4MB]>http://www.trance.co.jp/wiki/index.php?down=jpa_hibernate-sample2.zip]]
//** アノテーション一覧 [#jd01ea3f]
//|アノテーション|説明|記述場所|要素|要素説明|
//|@Entity|Entity Beanであることを定義|クラス|||
//|@Tabel||
//|@Id||
//|@Column||
//|||