ラベル JPA の投稿を表示しています。 すべての投稿を表示
ラベル JPA の投稿を表示しています。 すべての投稿を表示

2013年2月20日水曜日

@Enumerated

JPA に @Enumerated というアノテーションがあるのですが、今日はこの子にがっかりさせられました。

    @Enumerated(EnumType.ORDINAL)
    private HogeEnum hoge = HogeEnum.OFF;

とかするわけなんですが、これだとこちらにあるとおり、列挙型を定義した順に、0,1,2 の順の値しか持てないんですね。(当たり前といえば当たり前なのかもしれないけど・・・・)
http://tomee.apache.org/examples-trunk/jpa-enumerated/

仕方ないので、EnumType.STRING としとくと、上記の例だと「OFF」という文字列が入ります。列挙型に定義する順序は重要だと思うので、こちらのほうがいくらかマシですね・・・・

2013年1月29日火曜日

JPA2 Metamodel

JPA2 には、TypeSafe の施策として Metamodel という概念があるようです。
以下のサイトのように、「エンティティ名」+「_.」 +「カラム名」みたな感じで使うことになるようです。
http://www.ibm.com/developerworks/java/library/j-typesafejpa/

具体的な Metamodel の記述方法は以下のサイトが参考になりますね。
http://d.hatena.ne.jp/hayassh/20091027/1256656564

さらに、Hibernate JPA 2 Metamodel Generator というがあるようです。
http://docs.jboss.org/hibernate/jpamodelgen/1.0/reference/en-US/html_single/

本音を言えば、JPA2 が変更時の同期も含め、自動的に作ってくれるのがうれしいですが、少なくとも TypeSafe できますよ。というお話でした。

2013年1月28日月曜日

JPA Criteria API by samples

JPA Criteria と通常の JPQL の対比サンプル。並べてもらえるとわかりやすいですね。

JPA Criteria API by samples — Part-I | by altuure | altuure | Medium
JPA Criteria API by samples — Part-II | by altuure | altuure | Medium

※2022/4/4 リンク切れのため修正

2011年4月19日火曜日

フェッチジョイン

JPQL において、良くある疑問としては、どのようにして JOIN 戦略を利用すれば良いか、というものがあります。

フェッチジョインという機能が用意されており、これを利用します。
http://docs.redhat.com/docs/ja-JP/JBoss_Enterprise_Application_Platform/5.0/html-single/Hibernate_Entity_Manager_Reference_Guide/index.html#queryhql-joins

なので、基本的には、クエリビューは利用しません。
それでも、どうしてもビューを利用しなければならないケースも要件としては出てくる場合がありますね。
この場合は、仕方ないので以下のような形で JPQL を騙して?利用する形になります。
http://bochi.vyw.jp/2010/11/jpadatabase-view.html

ただし、トラブルの元なので、出来るだけフェッチジョインを利用するようにしましょう。

フェッチジョインを使うことで、エンティティの関連が、LAZY フェッチを選択していたとしても、これを上書いて、EAGER フェッチで一気に読み込むことが出来ます。
一覧画面などで、LAZY フェッチでパフォーマンスが問題となるような場合に、EAGER フェッチを利用したくなるケースが出てくると思いますので、このような場合に利用すると良いでしょう。

2010年12月18日土曜日

flushMode=FlushModeType.MANUAL 別解

メンバーがブログを見て教えてくれたんですが、以下の件は、

http://bochi.vyw.jp/2010/12/beginflushmodeflushmodetypemanual.html

components.xml に以下を記述することでデフォルト設定とすることも出来るんですね。
<core:manager default-flush-mode="MANUAL" />
マニュアルにも記述がありました。
http://docs.jboss.org/seam/2.1.0.GA/reference/ja-JP/html/persistence.html#d0e7121

ただし、メンバー曰く、pages.xml で対話を開始しなければいけないとか。アクション側で@Beginする場合は対象外となるようなので、注意してください。

2010年12月13日月曜日

@Begin(flushMode=FlushModeType.MANUAL)

JPA と Stateful Session Bean を組み合わせる場合で、普通にやろうとすると絶対に失敗するので、ある意味残念なお話ではありますが、本当に単純な操作以外のことをする場合において、

@Begin(flushMode=FlushModeType.MANUAL)

がほぼ必須となります。これを書くと、明示的に flush() メソッドをコールするまで、勝手に merge() されることはなくなる。
知らないと本当に苦労するので、Seam 開発をする上では重要な豆知識。

これを知らないが為に、Seam 開発なのに、Stateless Session Bean を使おうとするケースがちらほら見えるのですが、それをしてしまうと、Seam としては残念な感じになってしまうという。

※参考
http://m97087yh.seesaa.net/category/5908902-3.html

2010年12月3日金曜日

EntityManager#flush() が実行されるタイミング

 * トランザクションがcommitされるとき。
 * Queryが実行される直前。
 * EntityManager#flush()が呼ばれたとき


※参考
http://www.knowd.co.jp/yamazaki/index.php?q=node/29

2010年11月10日水曜日

JPAでDatabase View?

かつて、「どうしてもDatabase ViewをJPAで使いたくて、試行錯誤した」ときの記憶を思い起こす機会が最近あったので、メモメモメモメモ。


  • Entityはgenerate-entities等で作成しても意味不明なごみがくっついてくるので、手で作成した方が早いということで、Database Viewのエンティティは手作成の運用をしていたと記憶が
  • 当り前なのですが、DAOで更新系の実装をすると怒られます。
  • persistence.xmlで<property name="hibernate.hbm2ddl.auto" value="none"/>が必須になります。(create-dropとかにすると、その名前のテーブルを作成しに行って、同一名称のViewが存在している旨のエラーがデプロイ毎に吐き出されます。)
  • 作成するEntityはそのViewがテーブルだと思って作成して差し支えないのですが、Viewとほかのエンティティでさらに@OneToManyとかやりだすと苦しいと思います。
  • 当時の用途はリスト表示個所だったのですが、リストから詳細ページに入る際に詳細ページ側でテーブルのエンティティを再取得することになるかと思います。このことがStateful Session Bean/対話との相性が微妙になる気もしますので、留意が必要かもしれません。当時は、対話を詳細ページにGETパラメータでキーを渡して、詳細ページから対話を開始するようにしていました。(多分)
  • まぁ、そういう意味で現時点では色々とアレなので、fetch=FetchType.EAGER等でテーブルだけのORMで代用できないか検討した方が良いかと思います。簡単な深くない結合であれば十分代用可能と思います。


あくまでも、僕はこう逃げたというお話なので、重々注意をしてください。


※参考
http://www.adam-bien.com/roller/abien/entry/mapping_jpa_entities_on_view
なんか見れないのでGoogleキャッシュも
http://webcache.googleusercontent.com/search?q=cache:VUnfCPteIlIJ:www.adam-bien.com/roller/abien/entry/mapping_jpa_entities_on_view+jpa+database+view&cd=2&hl=ja&ct=clnk&gl=jp

2010年5月24日月曜日

SQLiteでJPA

何故なのか不明ですが、Hibernateでは標準でSQLiteに対応していない模様。
なので、SQLiteDialectを作ってやらなくてはなりません。

persistence.xmlでSQLiteDialectを指定してやります。

<property name="hibernate.dialect" value="foo.SQLiteDialect"/>

こんな感じ。それ以外にはどこといって替わったところはありませんが、Sqliteman開いてると何故かテーブルロック状態になります。苦笑。