Java EE 6 With Scala

さて、JavaEE6をGroovyで記載していたのとは取って代わってScalaでやってみました。
思ったよりも容易だったし、実用的に感じました。

DB設計者の悩みを解決するtrait

DBの設計をしていると必ず頭を悩ませる問題があります。
それはtypoです。

両手で数えられる程度のテーブル数であれば良いのですが、テーブル数が3桁を超えたりすると、管理がものすごく煩雑になります。
同じ名前のカラムもたくさんできて、それらを整合性を保ったまま管理するというのが非常に辛いのですが・・・・・
本当にtypoは悩ましい。
どこのDBを参照しても必ず一つはtypoがあり、かつそれが直せない状態。
テーブルの内容を他のテーブルに移し替える時にこのtypoを考慮しながら移すというのは非常に心が折れます。

例:

table1
   column1
   column2

table2
   colamn1
   column2

複数のテーブルに同じカラムが定義されているはずなのに、カラムが見つからない。よくよく見たらtypoだったという経験はだれでもあるのではないでしょうか。
そんなのに苦労したこと無いぜーとかいう人はきっとtypoを全くしない人か、DBの設計をやったことがないのか、typoに気がつくほどの頭がないのかの3択だと思います。

JavaEE6では一般的なO/Rマッパーと同じようにエンティティからテーブルを生成することができます。
エンティティをScalaで書くことにより、このtypoを防ぎやすくすることができます。

Scalaのtrait

traitとは何か。という人は hishidamaさんのScalaトレイトメモを参照していただくとして、traitはミックスインできるということが重要になります。
ミックスインを聞いたことがない人向けに一言で説明すると、多重継承です。複数のtraitを継承できます。

カラムごとにtraitを定義して、エンティティからはそのtraitをミックスインするようにすれば、テーブルごとにtypoによってカラム名が違うということを防ぐことができます。

  • trait
trait Title {
  @Column(nullable = false)
  @BeanProperty //getter,setterを生成する。
  var title: String = _
}
  • 複数のtraitを継承(ミックスイン)
@Entity
class Book extends EntityBase with Title with Price with ISBN
       with NumberOfPage with Illustrations {
}

各プロジェクトでユビキタス言語を作ったもののtypoにより残念な結果にという状態からはこれでおさらばでしょう。
しかし、きちんとユビキタス言語を作るという工程は必要です。
//正直言って、記載方法としてはキモいのが難点。

普通に書けるJSF(managed-bean)及びにEJB

Groovyの時には結局動かなかった非常に苦労したEJBですがScalaではきちんと書くことができます。
ただ、Groovyの時と同様、Scalaも自動的にScalaObjectというインターフェースがimplementsされるため、@LocalBeanアノテーションを付ける必要があります。

@Stateless
@LocalBean
class BookEjb extends CrudEjb[Book]
 
/** Provides basic CRUD support using an injected JPA entity manager. */
trait CrudEjb[E] {
  @PersistenceContext(unitName="default")
  protected var manager: EntityManager = _
 
  def create(entity: E): E = {
    manager persist entity
    entity
  }
 
  def readAll()(implicit m: Manifest[E]) = manager createNamedQuery ("findAll" + m.erasure.getSimpleName) getResultList
 
  def read(id: Long)(implicit manifest: Manifest[E]): E = manager.find(manifest.erasure, id).asInstanceOf[E]
・・・

Scalaでは括弧やピリオドが省略できるため、Javaに比べると自然に読めるように感じるのは気のせいでしょうか。*1

まとめ

JavaEE6をScalaで書くというのは思ったよりも便利だと思いました。
エンティティだけでもScalaで記載するとJavaEE6プロジェクトでのDB設計者の負荷が減るのではないかと思います。

なお、今回作ったソースは以下にコミットしてあります。
https://github.com/megascus/JavaEE6Scala


参考
Java EE 6 and Scala

Beginning Java EE 6~GlassFish 3で始めるエンタープライズJava (Programmer's SELECTION)

Beginning Java EE 6~GlassFish 3で始めるエンタープライズJava (Programmer's SELECTION)

Scalaスケーラブルプログラミング第2版

Scalaスケーラブルプログラミング第2版

追記

今回はNetBeansでつくってみたのですが、NetBeansScalaサポートはまだまだ未完成な状態なので、やる場合はNetBeansではやらないほうが良いです。Eclipseは宗教的な理由により使えないし、IntelliJは無償版だとJavaEEには対応していないため、試せていません。
だれか試した方がいらっしゃったら使い勝手について教えてくださると嬉しいです。

*1:複雑なことをしなければ