HOME > 技術情報 > Java > Java Persistence API

Java Persistence API 1.0(JPA)

Java Persistence APIとは

  • Javaオブジェクトの永続化のためのAPI
    以前はEJBの仕様に含まれていたものが、EJB3.0より切り離され、EJBコンテナ以外での使用が可能となった.
    また、O/Rマッピング、アノテーションを使用することにより、以前のEJBのような複雑な仕組みではなく、よりPOJOとして開発できるようになった.

特徴

  • アノテーションによるマッピング
    • XML設定ファイル減
    • コード量減
  • 4つのエンティティ状態(ライフサイクル)
    状態説明Persistent IndentityPersistence Context
    newEntityが生成された状態持たない結びつきなし
    managedEntityがEntityManagerに管理されている状態持つ結びつきあり
    removedEntityが削除予約となっている状態持つ結びつきあり
    detachedEntityがデータベースと関連がなくなった状態持つ結びつきなし

実装プロダクト

Java Persistence APIは仕様であるため、実装プロダクトがいくつか存在する.

  • Hibernate
  • TopLink
  • OpenJPA

使用方法 - 準備 (実装プロダクト:Hibernate)

今回は、実装プロダクトとして、「Hibernate」を使用する.

インストール

  • ダウンロード
    以下のサイトより、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

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>
  • 解説
    • <class> - EntityBeanクラスの定義
      パッケージ名を含むクラス名を定義することで、JPAで使用するEntityBeanとみなされる.
  • <properties> - JDBC接続情報の定義
    Hibernateの<property>タグのname属性値
    <property>タグのname属性値説明
    hibernate.dialect使用するDBクラス
    hibernate.connection.driver_classDBドライバクラス
    hibernate.connection.usernameユーザ名
    hibernate.connection.passwordパスワード
    hibernate.connection.urlDBのURL
    hibernate.hbm2ddl.auto自動的にDDLを有効にしデータベース出力する
    validate:
    update:
    create:
    create-drop:
    hibernate.show_sqlログにSQLを表示するか
    true:表示する
    false:表示しない
    hibernate.format_sqlログに表示したSQLをフォーマットするか
    true:フォーマットする
    false:フォーマットしない
    hibernate.use_sql_commentsSQLコメントを表示するか
    true:表示する
    false:表示しない

使用方法 - 実装 (単独テーブルへの追加、変更、削除、参照)

以下のテーブルを操作するサンプルを作成する.
テーブル名:User

フィールド種別主キー
idvarchar(255)
ageint(11)
namevarchar(255)

Entity Bean

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となる.
    • @Entity - Entity Beanであることを定義
      クラス定義の前に「@Entity」を記述し、「Entity Bean」であることを定義する.
  • @Table(name="User") - このEntity Beanとマッピングするテーブル名を定義
    クラス定義の前に「@Table(name="User")」を記述し、name要素にマッピングするテーブル名記述する.
    クラス名テーブル名が同じ場合は、「@Table(name="User")」は省略できる.
  • @Id - Primary Keyを定義
    「Primary Key」となるインスタンス変数に定義する.
  • @Column(name="id") - このインスタンス変数とマッピングするカラム名を定義
    インスタンス変数定義の前に「@Column(name="id")」を記述し、name要素にマッピングするカラム名を記述する.
    インスタンス変数名とカラム名が同じ場合は、「@Column(name="id")」は省略できる.

EntityManager

EntityManagerは、Entity Beanの永続性を管理するためのオブジェクト.
EntityManagerは以下のようにして取得する.

// 永続化
EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-sample");
EntityManager entityManager = factory.createEntityManager();
  • 解説
    • Persistence.createEntityManagerFactory("jpa-sample"); - EntityManagerFactoryを取得
      Persistence#createEntityManagerFactory()を使用し、EntityManagerFactoryを取得する.
      引数に、設定ファイル「persistence.xml」で記述した「persistence-unit name="jpa-sample"」の「jpa-sample」を渡す.

hibernate.hbm2ddl.autoによるDDL

   create table User (
       id varchar(255) not null,
       age integer not null,
       name varchar(255),
       primary key (id)
   ) type=MyISAM

サンプル

データベースへの、新規追加(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));
	}
}
  • 解説
    • 新規追加(Insert) - EntityManager#persist(Object[EntityBean]));
      1. Entityオブジェクトを生成する
        ライフサイクル -> new
        User user = new User();
      2. Entityオブジェクトに追加する値をセットする
        user.setId("1");
        user.setName("Insert");
        user.setAge(10);
      3. トランザクションを開始する
        entityManager.getTransaction().begin();
      4. Entityオブジェクトを永続化する
        ライフサイクル -> managed
        entityManager.persist(user);
      5. コミットする
        entityManager.getTransaction().commit();
      • 発行されるSQL
           insert 
           into
               User
               (age, name, id) 
           values
               (?, ?, ?)
  • 更新(Update) - EntityManager#merge(Object[EntityBean]);
    1. 更新するEntityオブジェクトを取得する.
      ライフサイクル -> managed
      User user2 = entityManager.find(User.class, "1");
    2. Entityオブジェクトに更新する値をセットする
      user2.setName("Update");
    3. トランザクションを開始する
      entityManager.getTransaction().begin();
    4. 永続化しているEntityオブジェクトとマージする
      ライフサイクル -> managed
      entityManager.merge(user2);
    5. コミットする
      entityManager.getTransaction().commit();
    • 発行されるSQL
         update
             User 
         set
             age=?,
             name=? 
         where
             id=?
  • 削除(Delete) - EntityManager#remove(Object[EntityBean]);
    1. 削除するEntityオブジェクトを取得する
      ライフサイクル -> managed
      User user2 = entityManager.find(User.class, "1");
    2. トランザクションを開始する
      entityManager.getTransaction().begin();
    3. Entityオブジェクトを削除する
      ライフサイクル -> remove
      entityManager.remove(user2);
    4. コミットする
      entityManager.getTransaction().commit();
    • 発行されるSQL
         delete 
         from
             User 
         where
             id=?
  • 主キーによる参照(Select) - EntityManager#find(EntityClass, String[primary key]);
    1. 主キーを指定して、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=?
  • まとめ
    • DBアクセス
      InsertEntityManager#persist(Object[EntityBean]));
      UpdateEntityManager#merge(Object[EntityBean]);
      DeleteEntityManager#remove(Object[EntityBean]);
      Select (Primary Key)EntityManager#find(EntityClass, String[primary key]);
  • トランザクション
    トランザクション開始EntityManager#getTransaction()#begin();
    コミットEntityManager#getTransaction()#commit();
    ロールバックEntityManager#getTransaction()#rollback();

サンプルダウンロード

使用方法 - 実装 (1対多、多対1)

以下のテーブルを操作するサンプルを作成する.
テーブル名:OrderInfo

フィールド種別主キー
idint(11)
datedatetime

テーブル名:OrderInfoDetail

フィールド種別主キー
idint(11)
productNamevarchar(255)
productPriceint(11)
quantityint(11)
orderInfo_idint(11)

Entity Bean

「@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;
	}
}
  • 解説
    • @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;
	}

}
  • 解説
    • @ManyToOne - 多対1のリレーションであることを定義
      インスタンス変数の前に「@ManyToOne」を記述する.

persistence.xml

上記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

   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)

サンプル

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
    iddate
    12007-09-26 10:23:33

OrderInfoDetail

idproductNameproductPricequantityorderInfo_id
1商品名1100011
2商品名2200021
  • 解説
    • 1対多
      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=?

           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
  • 多対1
    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

サンプルダウンロード


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2007-09-18 (火) 11:35:18 (6157d)