grails

Grails 2.4で追加されたdoWithSpring、doWithConfigについて

※この記事はGrails 2.4.3を元に記述しています Grails 2.4からdoWithSpring、doWithConfigといったユニットテストの仕組みが導入された。 これを使うとユニットテスト内でSpringビーンを定義したり、コンフィグの値を変更したりできる。 doWithSpring、doWit…

Grailsの追加、更新、削除処理について深く考える

※この記事はGrails 2.4.2をベースに記述しています 一見簡単にみえるが、意外と奥が深い。 次のようなドメインクラスがあったとする。 class Person { String username static constraints = { username unique: true } } この時、デフォルトのスキャフォル…

GrailsのSpring Security Core Pluginでパスワードのソルトとストレッチング

パスワードをハッシュで保存して置くのは当たり前ですが、レインボーテーブル使用した総当たり探索の対策として、ソルトとストレッチングを組み合わせ、より安全にパスワードを保存するのが一般的になってきました。 GrailsのSpring Security Core Pluginは…

Struts1ユーザにGrailsをオススメする6の理由 - The search is over -

Struts1のEOLがアナウンスされました。 最後のリリースから長く時間が経過しており、実質開発は終了している状態でしたが、このタイミングでのアナウンスとなりました。 アナウンスの中では、次の乗り換え先として、Struts2・Spring Web MVC・Grails・Stripe…

GrailsでCucumberを使用する

Ruby、Railsの世界では、プレーンテキストで記述できる受け入れテストツールとして有名なCucumberですが、Pure-Javaで実装されたcucumber-jvmのお陰で、Grailsでもプラグインをインストールすることで簡単にcucumberが利用できるようなります。 準備 cucumbe…

GrailsでアノテーションベースでBeanを登録する

元ネタ Grailsではgrails-app/serviceディレクトリ配下などにクラスを置くと自動的にSpringのbeanとして認識されますが、src/groovyやsrc/javaといったディレクトリでは自動的にはbeanとして登録されません。 src/groovy、src/java配下のクラスをbeanとして…

Database Migration Pluginでcontextを使用する

LiquibaseではchangeSetにcontext属性が設定できます。このcontext属性を使用することで、実行時に適用するchangeSetの範囲を指定できます。 databaseChangeLog = { changeSet(author: "yamkazu", id: "default-ctx") { ... } changeSet(author: "yamkazu", …

Database Migration Pluginで毎回実行するchangelogを定義する

runAlways属性をtrueに設定することで毎回実行するchangelogを定義できます。runOnChange属性がtrueの場合ではchangesetのチェックサムが変更になった時のみ実行しますが、runAlways属性をtrueにするとチェックサム変更有無に関係なく毎回実行してくれます。…

Database Migration PluginでNotNull制約のカラムを追加する

既存のデータが存在する場合に、NotNull制約が付与されたカラムを追加する場合は少し工夫が必要です。単にカラムを追加すると既存のデータがNULLになってしまうためエラーとなります。これを回避するには一度NotNull制約を付与せずにカラムを追加し、既存デ…

Database Migration Pluginで任意のSQLを実行する

Database Migration PluginではLiquibaseで使用可能なchangesetのコマンドが、groovyフォーマットのchangesetでも同様に使用可能になっています。 使用可能なコマンドの一覧はLiquibaseのリファレンスを参照してください。 今日はこの中からCustom SQLとCust…

Database Migration Plugin のチェックサム

データベースへの反映履歴を管理するdatabasechangelogテーブルにはmd5sumというchangesetのチェックサムを格納するカラムがあります。 liquibaseのリファレンスには以下のように記述されています。 LiquiBase が変更セットに到達すると、MD5Sum を計算して…

Grailsのcriteriaでlikeにescapeを指定する

どうも見つからない。いろいろ探してたらorg.hibernate.criterion.LikeExpressionなるものを発見したがorg.hibernate.criterion.Exampleで使われているくらいで他に使われていない。なんぞこれ。とりあえず、これを使おう。LikeExpressionはコンストラクタが…

Database Migration Pluginがすごい ~ロールバック編~

前回の続きDatabase Migration Pluginのすごいところはロールバックが出来る事。ロールバックを行うコマンドは主に3つ種類がある。 dbm-rollback-count dbm-rollback-to-date dbm-rollback それぞれ個別に見ていく。 dbm-rollback-count dbm-rollback-count…

Database Migration Pluginがすごい ~入門編~

ずっと放置していたけどDatabase Migration Pluginを触ってみた。やばい。これは使わないと。実際にアプリケーションを作りながら説明してく。とりあえずプロジェクトを作成。 $ grails create-app database-migration-test 作成したらBuildConfig.groovyを…

GrailsをIntellijからリモートデバッグする

いまだにprintfデバッグを卒業出来ません。そんなことはどうでもよくてリモートデバッグしてみる。山本さんの http://d.hatena.ne.jp/mottsnite/20120705/1341495778 に書いてあるとおり2.1からデバッグする際は-debugオプションを使ったほうが良いとのこと…

grailsのHibernateでSQLのパラメータまで出力する

元ネタ http://burtbeckwith.com/blog/?p=1604grailsでSQLを出力する方法は2通りあってDataSource.groovyで dataSource { ... logSql = true } とするか、Config.groovyで log4j = { ... debug 'org.hibernate.SQL' } とするか。前者は標準出力で、後者はロ…

grails2.1.1で追加されたfirst()、last()

grails2.1.1からドメインのメソッドにfirstとlastが追加されています。http://grails.org/doc/latest/ref/Domain%20Classes/first.html http://grails.org/doc/latest/ref/Domain%20Classes/last.html使い方は Book.first() Book.first('title') Book.first(…

Grails 2.1 から標準でインストールされているCache Pluginを試す

http://grails.org/plugin/cache がgrails 2.1からデフォルトでインストールされています。実態としてはSpringのCache Abstractionを薄くラップしたような形です。Serviceのメソッドや、Controller、またはGSPのレンダリングをキャッシュできます。メソッド…

GrailsでJSONの独自Marshallerを登録する

元ネタ http://compiledammit.com/2012/08/16/custom-json-marshalling-in-grails-done-right/有名な話なのかもしれませんが、独自Marshaller登録できるんですね。知らなかった。GrailsではJSONレスポンス書き出し方に代表的な2つのやり方が存在します。 ht…

GrailsでドメインクラスにMapのプロパティを定義するとどうのようなスキーマになるか

class MapHolder { Map mapValues } schema-exportすると以下になりました。 create table map_holder ( id bigint generated by default as identity, version bigint not null, primary key (id) ); create table map_holder_map_values ( map_values bigi…

Grailsでone-to-manyの関連をラッパークラス型で定義するとどの様なスキーマになるか

class WrapperValueHolder { static hasMany = [stringValues: String, integerValues: Integer, booleanValues: Boolean] } schema-exportしてみる。 create table wrapper_value_holder ( id bigint generated by default as identity, version bigint not…

Grailsの関連の型での動作の違いを理解する

ドメイン間の関連の型をどの様に設定するかでの挙動の違いです。リファレンスに書いてあることですが、いろいろ動かしながら検証してみました。ログとかだらだら長くて見にくいですが、面白いので貼り付けときました。Bookドメイン class Book { String titl…

GrailsのTaglib使っててid属性がどこかへいってしまう

htmlのid属性と、grailsのlink生成のためのドメインIDが混在していてややこしいのですが、例えばg:link <a href="/appname/book/list" id="book-list">book list</a> というようなHTMLを期待して <g:link controller="book" action="list" id="book-list">book list</g:link> といういうふうにg:linkを使うと実際には <a href="/appname/book/list/book-list">book list</a> となってしまいます。これをg:…

Grailsでテーブル毎にシーケンスを自動生成する方法

参考 http://grails.1312388.n4.nabble.com/One-hibernate-sequence-is-used-for-all-Postgres-tables-td1351722.htmlむかしJIRAにもチケット上がっていたみたいですが、 http://jira.grails.org/browse/GRAILS-3138 GrailsとうかHibernateの問題なのでclose…

GrailsのValidationMessageでクラス名とかプロパティ名のi18n対応をどこでやっているのか

grails2.1.0での情報。org.codehaus.groovy.grails.validation.AbstractConstraint#rejectValueWithDefaultMessageで処理している。 ... final Locale locale = LocaleContextHolder.getLocale(); final Class constrainedClass = (Class) args[1]; final St…

GORMでのコンポジション

リファレンスの内容そのままですが、同じ項目群を複数持つだとか、DB上の項目が多いからグルーピングしたいといった時にコンポジションが使えます。この場合テーブル上は1テーブルで表現されますが、アプリケーション側からは対応するクラスに分割して扱えま…

GORMでの継承とデータベーススキーマ

GORMでの継承によってデータベース上でどのようにスキーマ定義するかというお話です。Grailsのデフォルトの継承戦略はtable-per-hierarchyになっています。例えば次のようなドメインがあったとします。 class Parent { String name } class Sub1 extends Par…

自己参照っぽいツリーぽいあれをGORMで表現する

こういうやつです。それぞれがひとつのNodeというインスタンスで表される。 class Node { String name static belongsTo = [parent: Node] static hasMany = [children: Node] static mappedBy = [children: "parent"] } belongsToとhasManyしてしてマッピン…

Grailsでtest-app実行時の標準出力はどこいってしまったんやー

デフォルトだとtest-appした際に標準出力は、どこかいずこへもっていかれコンソールに表示されません。ちょっとした機能確認の為にUnitTestを使って学習テストなどやっていると、ついついprint使いたくなってしまうのですが、なぜかコンソールに出力してくれ…

GrailsでHibernateのSQLログを出す

DataSource.groovyでloggingSqlをtrue、formatもしたい場合はformatSqlをtrueに。 dataSource { ... loggingSql = true formatSql = true } おなじDataSource.groovyで hibernate { show_sql = true format_sql = true ... } としても同じ。こんな感じで出る…