だらだらと思いついたこととか書くブログ

エンジニア的なネタとか備忘録とかを書いていく予定

spring-data-jpaを使った場合の単方向と双方向について

spring-data-jpaを使った場合の単方向と双方向についてよく分からなかったので、自分なりに調べたことなどをまとめてみました

単方向

  • 後から双方向にデータをたどりたいといった時に単方向で作ってしまうと改修に手間が掛かる可能性がある

one側

@Entity
@Data
public class Department implements Serializable {
    
    @Id
    @Column(name = "department_id")
    private String departmentId;

    @OneToMany(name  ="member_fk", referencedColumnName="member_id", nullable = false)
    private List<Member> members;
}

many側

@Entity
@Data
public class Member implements Serializable {
    
    @Id
    @Column(name = "member_id")
    private String memberId;

}

双方向

双方向には下記の2パターンが存在する

  • mappedByを使う方法
  • @JoinTableを利用する方法
    • あいだにテーブルを仲介する場合に利用

mappedByを使う方法

  • @OneToManyアノテーションを付けて、mappedByで関連させる相手側エンティティのフィールドを指定する
    • 相手側(多側)で外部キー用のフィールドを持つ必要がある

one側

@Entity
@Data
public class Department implements Serializable {
    
    @Id
    @Column(name = "department_id")
    private String departmentId;

    @OneToMany(mappedBy="departmentFk")
    private List<Member> members;
}

many側

@Entity
@Data
public class Member implements Serializable {
    
    @Id
    @Column(name = "member_id")
    private String memberId;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "department_fk", referencedColumnName = "departmentId")
    private Department departmentFk;

}
JoinColumnアノテーションについて
  • 結合表のための外部キーカラム名を「name」で指定できる
  • 外部キーカラムによって参照された結合先テーブルのカラム名を「referencedColumnName」で指定できる
    • ※その場合は必ず結合先テーブルのプライマリキーとなっているカラムを指定
  • 複数の外部キーカラムがある場合は@JoinColumnsを使用して、それぞれの関連に対して@JoinColumnを指定する必要がある
  • @JoinColumnを明示的に指定しない場合は、リレーションが双方向でなく単方向に扱われてしまう

@JoinTableを利用する方法

※こちらは概要のみ

  • @JoinTableを使ってテーブル結合させ、joinColumnsと@JoinColumnを使って結合表のための外部キーカラム名を「name」で指定する
  • また、外部キーカラムによって参照された結合先テーブルのカラム名を「referencedColumnName」で指定する
  • 同時にinverseJoinColumnsと@JoinColumnを使って結合表のための相手側の外部キーカラム名を「name」で指定できる
  • それと合わせて、外部キーカラムによって相手に参照される結合先テーブルのカラム名を「referencedColumnName」で指定できる

単方向を使うべきか双方向を使うべきか?(※編集中)

単方向OneToManyをお薦めしない理由

子テーブルは対応する子オブジェクトにマップされないカラム(FK)を持つことになるから一般的じゃないってのが主な理由 もし単方向関連だったら、子オブジェクトは親オブジェクト無しでも存在できてしまう。もし親が必要だとしたら双方向ににするべきでは!?

ちょっと視点を変えて「関連の所有」という見方をすると・・(※ここは参考とだいぶ違うので理解が間違っているかも・・) 上記の例の場合だと、一対多の関連はどちらが所有してるのか?  → 直感的に考えるとdepartmentが複数のmemberを所有しているため「department」では?  → 実際は「member」、なぜならmemberは外部キーから関連するdepartmenetが辿れるが、departmentからは対応するmemberを辿れないため  → こうなってくると当初考えていたのと所有者が逆に・・ => ORマッパー的には逆のように見えてしまうため単方向を使うのは避けたほうがよい??

FetchTypeについて

データをDBから取得する際に関連テーブルの方も一緒に取り出すかどうかで下記の2タイプがある

  • LAZY → 取得しない(※正確には遅延ロード)
  • EAGER → 取得する

LAZY

  • 関連テーブルへのアクセスが発生したタイミングでロードされる
    • 元テーブルのみのアクセスの場合は関連テーブルのロードは行われない
      • フィールドの呼び出しを最初の呼び出しで行う

EAGER

  • 元テーブルにアクセスした際に関連テーブルも合わせてロードしデータが取得・格納される
    • そのフィールドにアクセスがあった時点でフィールドをデータベースから呼び出す

最後に

単方向・双方向のどちらを使うか、また使った際に各オプションをどうセットするべきかについてちゃんと理解しする必要があったため今回、まとめてみた

個人的には当初は外部キーはEntityクラスとして持たないほうが良いのでは?と思い単方向を使うつもりでいたが、関連についての記事などを見てみたりあらためて調べると双方向にシフトした方が、 本来の使い方や、今後の拡張性も考えると良さそうな気がしてきた。

ただし、この辺りはN+1問題や今回はあまり取り扱えていない「insertable,updateble,nullable」の辺りもしっかり理解した上で判断するのが良さそうなのでそのあたりについても調べてまとめる必要がありそう

参考させていただいた記事など

RESTについて

この記事について

マイクロサービスアーキテクチャを採用するにあたって各サービス間の通信方法としてRESTを使うことを想定していた 対応を進めていくにあたってそもそもRESTについて調べた際のメモ。 RESTにもいくつかの段階、レベルがあるということを知ったのでそちらについてのメモとなっています

RESTの成熟度レベル

  • Level 0:SOAPXMLでやりとりをするHTTP通信 → URI と HTTPが 1to1
  • Level 1:URLでリソースを表すようにする(リソースを動詞でなく名詞で表す)
  • Level 2:HTTPメソッド(GET, POST, PUT, DELETE)を正しく使い分けている
  • Level 3:レスポンスの中に関連するリンクを含める → HATEOAS

[アプリケーションのRESTful度合いをどう計測するか|https://www.infoq.com/jp/news/2011/05/measuring-rest] [RESTとは何か|http://qiita.com/aosho235/items/125af74e2eab66c7a816] [Richardson Maturity Model|https://martinfowler.com/articles/richardsonMaturityModel.html] [フロントエンド開発者の僕にもやっとわかった!RESTfulの本当の意味|https://www.webprofessional.jp/what-does-restful-really-mean/] [第3回 マイクロサービス アーキテクチャ 読書会 メモ|http://nashcft.hatenablog.com/entry/2016/09/08/014818]

JJUG CCC 2017 Springに行ってきた

今更ながら参加してきたので当日のメモなどを 本当に適当なメモ書きレベルなので後で編集したい・・

レガシーアプリケーションの巻き取りとモジュール分割

ブランチ運用

テスト(CI/CD) 単体 → junit(validation etc) 画面単体 結合

@Runwith(Enclosed.class) → レビューアに優しいテストコード

selenide → 自動テストに利用

SpotBugs

tool

コーディング規約ならCheckStyle 問題検出は、PMD、SpotBugs、CheckerFw、 error-proneから選ぶ感じ

findbugs

onlyAnalizeで対象クラスを絞る visitorsで利用detectorをけずる(何を優先してチェックするのか) → これは使いやすいと思うとのこと

Spring cloud stream

Batchをスケールアウトしたことで、ポーリングによるRDBへの負荷が高まった → spring cloud streamを使った仕組みにつくりかえ => イベントドリブンに作り変え

SCS(spring cloud stream)

  • メッセージドリブンなマイクロサービスが実装しやすい(pub-subモデル)
  • spring bootアプリケーション
  • consumer groups → レポート作成のスケールアウトが容易になった => これによりノードごとに別IDの処理が行えるようになった(Batchをスケールアウトしたことで、ポーリングによるRDBへの負荷が高まった)
  • binder application → アプリ-ミドルウェア間が疎結合になるらしい(共通のdestination設定でOK)

spring batch job管理テーブルに大量INSERTでエラー(Sink側のSpring Batchが大量に起動した時に、Job管理テーブルに大量のinsertが流れてエラーに… )

  • maxAttemptの調整 → これだけだと不十分
  • DeadLetterQueue → エラーリカバリ用のMQを用意 => SCSのautoBindDlqをtrueに する

→ただ根本対応にはなっていないのでJobRepository側の対応方法を調査中。。

ポーリング型からイベントドリブンに変えたことでスループットが向上

CloudFoundryへ移行してスケールアウトが容易にできるようにする  → cflogin, cfpush? => この辺も含めて謎なので調べてみる

c.f) 第2世代への作り変えについて https://www.slideshare.net/techblogyahoo/jjugccc-cccf1-phpjava

c.f) pulsar https://www.infoq.com/jp/news/2016/10/pulsar

Jigsaw

・module-info.java - dependency disclosure scope → JAR内のこのファイルにモジュールの依存を記述する(module-info.javaでjarのメタ情報(依存性と公開範囲)を管理してModule化)

java –list-modules、現状73個のモジュールがリストされる

Cookpad tech kitchen#8に参加してみた

Cookpad tech kitchen #8に当選できたので初参加して来ました 色々と経験出来たのでメモ

tech kitchenについて

まず、ガッツリ料理が出てきたのにびっくり。。 野菜もふんだんに使われていて、見た目も味もステキな料理が食べられてこれだけでも来た価値が・・とちょっと思ってしまった笑 飲み物も提供されていて、セッション始まるまでは何しに来たのかちょっとわからなくなるほどのおもてなし感

セッションについて

非同期なジョブ

  • ワーカーがスケーラブルではない  → キューをトリガーにdockerでワーカーが必要な分だけ起動する  → activejobとAWSSNS,SQSなど)を活用

  • Barbeque → ジョブキュー管理システム

  • Hako → コンテナ管理ツール

アプリとワーカーで同じイメージから起動しているため環境差分が無くスケールしやすい

kuroko2

クックパッドのジョブ管理システム

美しいバッチの壊し方

  • Bricolarge
  • 1ジョブ = 1SQL → よいバッチ(運用しやすいバッチ=障害の対応がしやすい)を作るため

美しいバッチとは!?

  • I/Oの対象ごと(DB、テーブル、ファイルなど)にジョブ分割
  • ジョブ管理システムで結合

http://www.shigemk2.com/entry/cookpad_tech_kitchen_8_3

Others

Hakoとは

dockerで賄えないDNSやDB接続情報なども設定ファイルで管理できる(?)ツール

https://techconf.cookpad.com/2017/yoshiori.html

DWHについて

DBA的な仕事もしつつアプリ(バッチ)もガッツリ書く ブリコラージでジョブ管理をしているのでバッチはほとんどRuby製(ただし、中にはシェルなどを呼び出している部分も・・) DWH(Amazon redshift)のキャパ的にはバッチ処理自体では全然余裕があるが、DEVやビジネスサイドで呼ばれるクエリ処理がガンガン来るため大変・・(グルーバル展開もしているため、それこそ一日中来てしまう。。)

Cookpadの開発環境について

本番と開発環境のDBのレプリケーションについて

本番DBと開発DBの間にもう1個DBがかまされている(※わかりやすさのため準本番とする) 本番DBから準本番DBへのレプリケーションステートメントベース 準本番から開発DBへのレプリケーションはレコードベース(IDが変わってしまうなどの問題があるため) 準本番から開発DBへのレプリは開発用のデータはID1から、レプリは必ず6万以上から、といったような感じでMySQLのAUTO INCREMENT(?)機能などを活用して運用している どうしてもレプリ時にエラーとなってしまうデータ(重複エラーなど)は無視する 詳しくはブログにも書いてあるとのこと

開発チーム、体制について

リリース(?)、システムははリクエストごとにdockerイメージがスケールしていくような構成になっている → スケーラブルな仕組み 開発チームはビジネスサイドのディレクターさんなども含めた2〜3人とかの小規模なチーム プロジェクトにチーム(人)が紐付いているような感じで体制は流動的

セッションはRubyAWSも使っているわけではないため概念的な部分とかしか理解できず、持ち帰れたものが少なかったかも・・ ただ、やっぱりバッチがどうあるべき、どういう問題を抱えていてこうした、みたいな話が聞けて良かったし、個別にお話させて頂いて色々聞けたのも良い機会でした!

ダンスレッスン@20170605

ダンスレッスン

ちゃんとしたプライベートレッスンを受けるの約2年ぶり・・ 久しぶりのレッスンかつ初めて習う先生、初めて行ってみたスタジオで色々と新鮮さや学びがあったので忘れないうちにメモ

 レッスン対象

チャチャチャ - バリエーション

 レッスン

全体

1個1個の音をはっきりさせる → 音を一つ一つ言いながら動けるくらいにはしておく 2人で動くところはどこの音の瞬間にどのアクションになるのかはっきりさせておく

出だし

4でキック、1でアクション 次は3で右足を寄せるところまでいく

1で振り向いたところ~

1でパートナーと合わせてアクション その後は右のアームを下げていきながら、床を踏んでボディテンションを上げていく

タイムステップetc

2&3で右にタイムステプ その後は4で左足を寄せる、&で左足に踏み変えながら180°回転、1で右足を踏む

シャッセで移動

1個の音(半拍)で踏み変えて、次の足を出して踏む直前まで動く 1個1個で出て踏んでいるようでは遅い

前に移動

右→左→右で前に移動、&で左、4で右足(+1で左足?) その後は4で自分が前に出ながらパートナーを引く(この時に右手でしっかり押さえる) 1で今度は自分が下がってパートナーを出す

入れ替わり~ランジ

4で左足体重で180°回転(この時、やや自分側に体を引く感じ) 1で右足に乗る 2で左足をやや入り気味に出して3でロンデして1でランジ

パートナーのスピン

パートナーがスピンするところではムリに回そうとしない(ワクを作ってパートナーが回転する場所を作ってあげるだけくらいのイメージ) 1でラインを作るきっかけを与えるだけくらいで良い

いろいろ教わったのでちゃんと動きながら理解してモノにしたいし、他のところでも使えるようにしないとな。。

ドメイン駆動設計 - Part.1

ドメイン駆動設計について調べてみた(その1)

まずは概念的なものをまとめてみる

ドメイン駆動設計

ドメインロジックの断片化

プレゼンテーション層

  • 画面の入出力

アプリケーション層

  • データ処理の手順

データソース層

  • データベース操作

ドメインロジックを"ドメインモデル"に集約する ドメインを学び学んだことをコードで豹男減する

分析設計(分析しながら設計する)

技法

オブジェクト指向

  • 抽象データ型 → 人間の知りたい事/やりたいことを定義する => 抽象化=人間の関心事に近づける
  • モジュール構造 → 抽象データ型を部品として全体を組み立てる

業務の知りたい事/やりたい事をクラス名とメソッド名で表現する

XP

変化に適応するソフトウェア開発

  • フェーズに分けない → 毎日少しずつ成長する
  • 効率を追求する

ドメイン駆動設計 分析しながら設計する - SlideShare https://www.slideshare.net/masuda220/ss-74962182

ドメイン駆動設計 基本を理解する https://www.slideshare.net/masuda220/ss-59756718

ダンスメモ@20170513

久しぶりにチャチャ&ルンバのベーシック中心のオシャレなフィガーとそれを踊るにあたってどう動けばいいのか?という内容についてのグループレッスンを受けたのでメモ

ChaChaCha

カール

思っている以上に早めにリードする → よく使うホッケースティックなどとは違う動きになることを早めに知らせる

後退~ファン

後退の時にはパートナーを自分の左前にリードする(それと真逆に自分が動く)  → 相手に来て欲しい位置と反対側に自分が移動する  => 自分の左(もしくはやや左後ろ)くらいにリードしてしまいがちなので注意する

クローズドヒップツイスト~スパイラル(?)

ワクでパートナーをリードしてから自分が右足に体重移動することでパートナーを自分の左に向けて前進させる  → そこから左にアームを上げてスパイラルのリード  => 回転後はしっかり左のアームを元の高さまで戻すことに注意

Rumba

アレマーナ

このルーティンでのアレマーナは通常と違うので左シェイプ(?)を掛けて行う

アレマーナのあと

アレマーナで掛けたシェイプを元に1カウントで入れ替わる  → この時、右足体重

ホッケースティック

ホッケースティックのあとは自分の右前(逆壁斜め)に対してオープンで出ていく感じになるので、アレマーナ~踏み変えの後の後退で自分が左後ろに後退してリードするようにする

感想

特にリード部分は結構、 ・よくよく考えるとそうだよなって思うところ や ・そういえばそう教わってはずだけどすっかり忘れてしまっていた ということがたくさんありとても勉強になったになった良い時間でした

あと、久しぶりにちゃんと色々と考えながら踊ったのもあり、何か「ホッケースティックでのチェック」や「キューバンロックスでのチェック」、はたまたランジの後のファンなど今更ながらどう踊るのが正解なのか迷子にになった。。

また定期的に練習するようにしたいな、と思っていることもあり、教わったことを実践できるようにしつつ、この辺の迷子課題の解決策を見つけたいところ ともあれ、やっぱりダンス楽しいし、新しいことを覚えられるのは楽しいなーとあらためて思えた一日でした

 参考

すっかり忘れていたのでダンスのアライメント、LODについて

socialdance.asia