LoginSignup
0
0

More than 5 years have passed since last update.

Salesforce と kintone 間で顧客データを同期する方法 (Java - JPA使用)

Last updated at Posted at 2017-05-19

Salesforce と kintone 間で顧客データを同期する方法として、CDataドライバーを利用したWindowsフォームアプリケーション(C#/ADO.NET)によるものを別記事でご紹介しました。
CDataドライバーは、ADO.NETのみならず様々なテクノロジーで提供されています。今回は、Salesforce と kintone 間で顧客データを同期するアプリケーションの Java による例をご紹介したいと思います。

000_構成図.png

このアプリケーションの概要は次の通りです。

  • JDK 8
  • JPA を利用
  • JavaFX によるデスクトップアプリケーション
  • Eclipse 4.6
  • Salesforce および kintone からデータを読み込む
  • インポートしたい行を選択して、Salesforce から kintone へデータをインポートする

それでは、このサンプルアプリケーションの開発手順を見ていきます。

ソースコード

このサンプルアプリケーションのソースコードはこちらからどうぞ。

CData製品のインストール

CData Software をインストールします。今回必要になるのは、次の2つです。

開発環境の準備

Eclipse 4.6 を使用します。以下の機能を Eclipse にインストールしておいてください。

  • Dali Java 永続化ツール - EclipseLink JPA サポート
  • Dali Java 永続化ツール - JPA サポート
  • e(fx)clipse - IDE

※ サイトのロケーションは http://download.eclipse.org/releases/neonhttp://download.eclipse.org/efxclipse/updates-released/2.4.0/site を使用

また、[ウィンドウ]->[設定]->[Java永続化]->[JPA]->[エラー/警告] で、[プロジェクト]のセクションを開き、「複数の永続化単位」の設定を「無視」にしておきます。

プロジェクト作成

新規プロジェクトを作成します。JavaFX Project を選択します。

001_プロジェクト作成.png

デフォルトのまま順次「次へ」ボタンをクリックしていきます。最後のダイアログでは、「言語」に"FXML"、「Root-Type」に"javax.scene.layout.AnchorPane"、「ファイル名」に"MainPane"、「Controller Name」に"MainPaneController"を指定し、完了ボタンをクリックします。

002_プロジェクト作成2.png

プロジェクトが作成されたら、プロジェクトを右クリックしてプロパティを開き、プロジェクト・ファセットで「ファセット・フォームへ変換...」をクリックします。プロジェクト・ファセット「JPA」にチェックを入れ、「より詳しい構成が必要...」リンクから次画面へ進みます。

003_1_プロジェクト作成3_ファセット_より詳しい構成が必要.png

JPAファセットのウィザードで、「ライブラリーをダウンロード...」ボタンをクリックします。

003_2_プロジェクト作成3_ファセット_JPAファセット.png

EclipseLink 2.5.2 を選択し、次へボタンをクリックします。

003_3_プロジェクト作成3_ファセット_ライブラリのダウンロード.png

ライセンス受諾チェックを入れ、完了ボタンをクリックします。
これによりワークスペースに EclipseLink がダウンロードされ、ユーザライブラリとして使用可能になります。

003_4_プロジェクト作成3_ファセット_ライブラリのダウンロード_ライセンス.png

[JPA実装]のユーザー・ライブラリで「EclipseLink 2.5.2」を選択し、「注釈付きクラスを自動的に発見」を選択してOKボタンをクリックします。

003_5_プロジェクト作成3_ファセット_ライブラリのダウンロード後.png

JDBCドライバーの登録

Eclipse に JDBC ドライバーを登録します。
[ウィンドウ]->[設定]->[データ管理]->[接続]->[ドライバー定義] を開き、追加ボタンをクリックします。
汎用JDBCドライバーを選択し、ドライバー名を "CData Salesforce Driver" とします。

008_2_テーブルからエンティティ_SF_接続プロファイル_ドライバー.png

「Jarリスト」タブを開きjarファイルを指定します。CData製品のインストール先/lib/cdata.jdbc.salesforce.jar を選択します。
次に「プロパティー」タブを開き、ドライバークラスと接続URLを設定します。それぞれ以下の値を設定します。

  • ドライバークラス:cdata.jdbc.salesforce.SalesforceDriver
  • 接続 URL:jdbc:salesforce:User=<ユーザ名>;Password=<パスワード>;Security Token=<セキュリティトークン>;

011_テーブルからエンティティ_SF_接続プロファイル_ドライバー4.png

kintone のドライバーも同様に登録します。ドライバークラス名や接続URLについては、マニュアルに記載があります。

データベース接続の作成

先程登録したJDBCドライバーを使用して、データベース接続を作成します。
ビュー「データ・ソース・エクスプローラ」を開きます。データベース接続を右クリックして「新規」を選択します。
接続プロファイル・タイプで汎用JDBCを選択し、名前を "CData Salesforce JDBC" とし、次へボタンをクリックします。

007_2_テーブルからエンティティ_SF_接続プロファイル.png

ドライバーは、先程作成した CData Salesforce Driver を選択します。
「データベース」はここではSAMPLEのままでかまいません。「ユーザー名」にユーザ名を入力し、完了ボタンをクリックします。

012_テーブルからエンティティ_SF_接続プロファイル_ドライバー5.png

同様にして、kintone のデータベース接続も作成します。

エンティティクラスの生成

Eclipse の機能を使用して、テーブル情報からエンティティクラスを生成します。

プロジェクトのプロパティからJPAを開き、接続に "CData Salesforce JDBC" を指定し、「接続からデフォルト・カタログを上書き」「接続からデフォルト・スキーマをオーバーライド」にチェックを入れ、それぞれ "CData" と "Salesforce" を選択してOKボタンをクリックします。

013_テーブルからエンティティ_SF_プロジェクトのプロパティ_デフォルトカタログ.png

次にプロジェクトを右クリック->新規で「その他」を選択し、[JPA]->[テーブルから JPAエンティティー]を選択して次へボタンをクリックします。
カスタム・エンティティーの生成ダイアログが開くので、「接続」で "CData Salesforce JDBC"、「スキーマ」で "Salesforce" を選択します。すると「テーブル」に Salesforce のオブジェクトの一覧が表示されます。
「Account」にチェックを入れ、次へボタンをクリックします。
※なおここで時間がかかる場合がありますが、そのまま待っていれば次の画面が表示されます。

015_テーブルからエンティティ_SF_エンティティ作成_テーブル選択.png

「クラス名」が "Account" になっていることを確認し、完了ボタンをクリックします。

015_テーブルからエンティティ_SF_エンティティ作成_作成.png

これで Account(取引先) のエンティティクラスが生成されました。
同様にして Contact(取引先責任者) のエンティティクラスも生成します。

kintone の顧客リストのエンティティクラスも同様に作成しますが、プロジェクトのJPAプロパティで接続、カタログ、スキーマを kintone のものに設定してから実施します。

013_2_テーブルからエンティティ_KT_プロジェクトのプロパティ_デフォルトカタログ.png

kintone の顧客リストのエンティティクラスも同様に作成します。

016_テーブルからエンティティ_KT_エンティティ作成.png

ここまでで3つのエンティティクラスが作成されました。
プロジェクトのJPAプロパティの接続等を未設定に戻しておきます。

017_テーブルからエンティティ_プロジェクトのプロパティ_戻し.png

永続化ユニットの定義

META-INF/persistence.xml を開き、以下を記述します。<Salesforceの接続URL> と <kintoneの接続URL> にはそれぞれJDBCドライバーの登録時に設定したものを指定します。

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="salesforce" transaction-type="RESOURCE_LOCAL">
        <class>application.Contact</class>
        <class>application.Account</class>
        <properties>
            <property name="eclipselink.jdbc.native-sql" value="true"/>
            <property name="javax.persistence.jdbc.url" value="<Salesforceの接続URL>"/>
            <property name="javax.persistence.jdbc.driver" value="cdata.jdbc.salesforce.SalesforceDriver"/>
        </properties>
    </persistence-unit>
    <persistence-unit name="kintone" transaction-type="RESOURCE_LOCAL">
        <class>application.顧客リスト</class>
        <properties>
            <property name="eclipselink.jdbc.native-sql" value="true"/>
            <property name="javax.persistence.jdbc.url" value="<kintoneの接続URL>"/>
            <property name="javax.persistence.jdbc.driver" value="cdata.jdbc.kintone.KintoneDriver"/>
        </properties>
    </persistence-unit>
</persistence>

処理の実装

エンティティクラス Contact の修正

Salesforce 側はContact(取引先責任者)が処理対象のオブジェクトですが、一部の項目はAccount(取引先)から取得したいものがあるため、Contactクラスを修正してAccountの項目を取得できるようにします。以下のコードを追加します。

    @JoinColumn(name="AccountId", referencedColumnName="Id")
    private Account account;

    public String getAccountName() {

        if (account == null) {
            return "";
        }

        return account.getName();
    }

    public String getAccountAddress() {

        if (account == null) {
            return "";
        }

        return account.getBillingState() + account.getBillingCity() + account.getBillingStreet();
    }

    public String getAccountBillingPostalCode() {

        if (account == null) {
            return "";
        }

        return account.getBillingPostalCode();
    }

MainPaneControllerの初期化

application/MainPaneController.java を開きます。空の実装になっているので、以下の初期化コードを入れます。
※適宜import文を追加します。

public class MainPaneController implements Initializable {

    @FXML
    private TableView<Contact> salesforceTable;

    @FXML
    private TableView<顧客リスト> kintoneTable;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        salesforceTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        kintoneTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        EntityManager em = Persistence.createEntityManagerFactory("kintone").createEntityManager();
        kintoneTable.getItems().addAll(em.createNamedQuery("顧客リスト.findAll", 顧客リスト.class).getResultList());

        em = Persistence.createEntityManagerFactory("salesforce").createEntityManager();
        salesforceTable.getItems().addAll(em.createNamedQuery("Contact.findAll", Contact.class).getResultList());
    }
}

インポート処理

インポート処理を実装します。以下のメソッドを追加します。

    @FXML
    private void importOnClick(MouseEvent event) {

        EntityManager em = Persistence.createEntityManagerFactory("kintone").createEntityManager();

        em.getTransaction().begin();

        for (Contact contact : salesforceTable.getSelectionModel().getSelectedItems()) {

            顧客リスト kintoneItem = kintoneTable.getItems().stream()
                .filter(o -> o.getメールアドレス().equals(contact.getEmail()))
                .findFirst()
                .orElse(new 顧客リスト());

            kintoneItem.setメールアドレス(contact.getEmail());
            kintoneItem.set会社名(contact.getAccountName());
            kintoneItem.set住所(contact.getAccountAddress());
            kintoneItem.set担当者名(contact.getName());
            kintoneItem.set部署名(Optional.ofNullable(contact.getDepartment()).orElse(""));
            kintoneItem.set郵便番号_数字のみ_(Optional.ofNullable(contact.getAccountBillingPostalCode()).orElse(""));
            kintoneItem.setTel_数字のみ_(contact.getPhone());
            kintoneItem.setFax_数字のみ_(contact.getFax());
            kintoneItem.set備考("");
            kintoneItem.set経度("");
            kintoneItem.set緯度("");

            if (kintoneItem.getRecordId() == 0) {
                em.persist(kintoneItem);
            }
        }

        em.getTransaction().commit();

        kintoneTable.getItems().clear();
        kintoneTable.getItems().addAll(em.createNamedQuery("顧客リスト.findAll", 顧客リスト.class).getResultList());
    }

c#版と同じく、メールアドレスをキーとして、Salesforce側のデータをkintone側に設定しています。
CDataドライバーを使用することにより、Salesforceおよびkintoneのデータをデータベーステーブルとして扱えるようになるため、このようにJPAを通した管理を行うこともできます。

画面の作成

最後に画面を作成します。application/MainPane.fxmlを開き、以下のコードを実装します。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="660.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/8.0.102" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainPaneController">
   <children>
      <TableView fx:id="salesforceTable" layoutX="14.0" layoutY="53.0" prefHeight="600.0" prefWidth="485.0">
        <columns>
          <TableColumn prefWidth="150.0" text="担当者名">
            <cellValueFactory><PropertyValueFactory property="name" /></cellValueFactory>
          </TableColumn>
          <TableColumn prefWidth="150.0" text="メールアドレス">
            <cellValueFactory><PropertyValueFactory property="email" /></cellValueFactory>
          </TableColumn>
          <TableColumn prefWidth="150.0" resizable="false" sortable="false" text="会社名">
            <cellValueFactory><PropertyValueFactory property="accountName" /></cellValueFactory>
          </TableColumn>
          <TableColumn prefWidth="150.0" text="部署名">
            <cellValueFactory><PropertyValueFactory property="department" /></cellValueFactory>
          </TableColumn>
          <TableColumn prefWidth="150.0" text="住所">
            <cellValueFactory><PropertyValueFactory property="accountAddress" /></cellValueFactory>
          </TableColumn>
        </columns>
      </TableView>
      <Button layoutX="542.0" layoutY="263.0" mnemonicParsing="false" onMouseClicked="#importOnClick" prefHeight="35.0" prefWidth="116.0" text="インポート" />
      <TableView fx:id="kintoneTable" layoutX="696.0" layoutY="53.0" prefHeight="600.0" prefWidth="485.0">
        <columns>
          <TableColumn editable="false" prefWidth="75.0" sortable="false" text="レコード番号">
            <cellValueFactory><PropertyValueFactory property="レコード番号" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="150.0" sortable="false" text="担当者名">
            <cellValueFactory><PropertyValueFactory property="担当者名" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="150.0" sortable="false" text="メールアドレス">
            <cellValueFactory><PropertyValueFactory property="メールアドレス" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="150.0" sortable="false" text="会社名">
            <cellValueFactory><PropertyValueFactory property="会社名" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="100.0" sortable="false" text="部署名">
            <cellValueFactory><PropertyValueFactory property="部署名" /></cellValueFactory>
          </TableColumn>
          <TableColumn editable="false" prefWidth="150.0" sortable="false" text="住所">
            <cellValueFactory><PropertyValueFactory property="住所" /></cellValueFactory>
          </TableColumn>
        </columns>
      </TableView>
   </children>
</AnchorPane>

ウィンドウのサイズを設定します。application/Main.java を開き、Sceneのサイズを変更します。

Scene scene = new Scene(root, 1200, 660);

実装は以上です。

実行

実行構成を作成します。[実行]->[実行構成]を開き、「Javaアプリケーション」を右クリックして「新規」を選択します。
クラスパスタブを開き、CDataのJDBCドライバーを2つ指定し、実行ボタンをクリックします。

018_実行構成.png

実行すると、テーブルビューにSalesforceとkintoneのデータが表示されたウィンドウが立ち上がります。

019_実行直後.png

データ移行したい行を選択して「インポート」ボタンをクリックすると、選択したデータが kintone に登録されます。

020_移行後.png

021_移行後kintone.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0