カスケード

今回はカスケードについてです。

【前提条件】

[環境]
[その他]
  • JPAの設定が完了している*1

【概要】

カスケードの設定はテーブル結合の設定時に行います。
設定値は列挙型である
javax.persistence.CascadeTypeクラスを使用します。

【サンプルコード】

[テーブル]

今回は以前作成した
「userdata」テーブルと「user_authority」テーブルを使います。

CREATE TABLE userdata
(
    user_id character varying(10) NOT NULL,
    name character varying(60),
    last_update timestamp with time zone NOT NULL DEFAULT now(),
    CONSTRAINT user_primary_key PRIMARY KEY (user_id )
)
CREATE TABLE user_authority
(
  seq_number serial NOT NULL,
  auth_user_id character varying(10) NOT NULL,
  authority_type integer,
  CONSTRAINT authority_primary_key PRIMARY KEY (seq_number )
)
[Entity]

エンティティのクラスです。

package jp.glory.persistence.entity;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "userdata")
@NamedQueries({
        @NamedQuery(name = "findAll", query = "SELECT u FROM UserData u"),
        @NamedQuery(name = "findByUserId", query = "SELECT u FROM UserData u WHERE u.userId = :userId"),
})
public class UserData implements Serializable {

    private static final long serialVersionUID = 6528642302239465812L;

    @Id
    @Column(name = "user_id")
    private String userId = null;

    private String name = null;

    @Column(name = "last_update")
    private Timestamp lastUpdate = null;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumns({
        @JoinColumn(name = "auth_user_id", referencedColumnName = "user_id")
    })
    private List<UserAuthority> authorityList = null;

    // アクセサメソッドは省略
}

カスケードの設定は
OneToOne、OneToMany、ManyToOne、ManyToManyアノテーション
cascade属性で行います。

CascadeTypeクラスには
ALL、PERSIST、MERGE、REMOVE、REFRESH、DETACHが
定義されています。

サンプルではALLを指定しています。

結合先のエンティティクラスには特別な設定は不要です。

package jp.glory.persistence.entity;

import java.io.Serializable;

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 = "user_authority")
public class UserAuthority implements Serializable {

    private static final long serialVersionUID = 1625221760062551052L;

    @Id
    @Column(name = "seq_number")
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "user_authority_seq_number_seq")
    private int seqNumber = 0;

    @Column(name = "auth_user_id")
    private String authUserId = null;

    @Column(name = "authority_type")
    private int authorityType = 0;

    // アクセサメソッドは省略
[persistence.xml]

persistence.xmlも特別な設定はしていません。
使用するエンティティクラスを定義しています。

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">

    <persistence-unit name="blog" transaction-type="JTA">
        <jta-data-source>jdbc/blog</jta-data-source>
        <class>jp.glory.persistence.entity.UserData</class>
        <class>jp.glory.persistence.entity.UserAuthority</class>
    </persistence-unit>
</persistence>
[EJB]

EJBのクラスは受け取ったUserDataクラスの
オブジェクトを受け取り登録を行うだけです。

package jp.glory.application;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import jp.glory.persistence.entity.UserData;

@Stateless
public class UserEntryApplication {

    @PersistenceContext(unitName = "blog")
    private EntityManager manager = null;

    public void entry(final UserData userData) {

        manager.persist(userData);
    }
}
[登録クラス]

登録を行うクラスです。
UserDataクラスのオブジェクト生成します。
作成したオブジェクトにUserAuthorityのListを設定します。

package jp.glory.ui;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

import jp.glory.application.UserEntryApplication;
import jp.glory.persistence.entity.UserAuthority;
import jp.glory.persistence.entity.UserData;

@ManagedBean(name = "userEntryPage")
@RequestScoped
public class UserEntryPage {

    @EJB
    private UserEntryApplication application = null;

    private String userId = null;

    private String name = null;

    private boolean authority1 = false;

    private boolean authority2 = false;

    private boolean authority3 = false;

    private boolean authority4 = false;

    public void entry() {

        final UserData userData = new UserData();
        userData.setUserId(userId);
        userData.setName(name);
        userData.setLastUpdate(new Timestamp(System.currentTimeMillis()));

        final List<UserAuthority> authorityList = new ArrayList<>();
        if (authority1) {
            authorityList.add(createAuthority(1));
        }

        if (authority2) {
            authorityList.add(createAuthority(2));
        }

        if (authority3) {
            authorityList.add(createAuthority(3));
        }

        if (authority4) {
            authorityList.add(createAuthority(4));
        }
        userData.setAuthorityList(authorityList);

        application.entry(userData);

        userId = null;
        name = null;
        authority1 = false;
        authority2 = false;
        authority3 = false;
        authority4 = false;
    }

    private UserAuthority createAuthority(final int authorityType) {

        final UserAuthority authority = new UserAuthority();
        authority.setAuthorityType(authorityType);
        authority.setAuthUserId(userId);

        return authority;
    }

    // アクセサメソッドは省略
}
[ページ]

登録用のページです。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html">
    <f:view>
        <h:head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <title>登録サンプル</title>
        </h:head>
        <h:body>
            <h:form id="entryForm">
                <div>
                    ユーザID:<h:inputText id="userId" value="#{userEntryPage.userId}" />
                </div>
                <div>
                    ユーザ名:<h:inputText id="name" value="#{userEntryPage.name}" />
                </div>
                <div>
                    権限1:<h:selectBooleanCheckbox value="#{userEntryPage.authority1}" />
                </div>
                <div>
                    権限2:<h:selectBooleanCheckbox value="#{userEntryPage.authority2}" />
                </div>
                <div>
                    権限3:<h:selectBooleanCheckbox value="#{userEntryPage.authority3}" />
                </div>
                <div>
                    権限4:<h:selectBooleanCheckbox value="#{userEntryPage.authority4}" />
                </div>
                <div>
                    <h:commandButton action="#{userEntryPage.entry()}" value="登録" />
                </div>
            </h:form>
        </h:body>
    </f:view>
</html>

【実行】

作成したページはで全部の項目に値を入力します。

登録ボタンをクリックすると↓のようなデータが登録されます。
[userdataテーブル]

[user_authorityテーブル]

両方のテーブルにデータが登録されていることがわかります。