grails
※この記事はGrails 2.4.3を元に記述しています Grails 2.4からdoWithSpring、doWithConfigといったユニットテストの仕組みが導入された。 これを使うとユニットテスト内でSpringビーンを定義したり、コンフィグの値を変更したりできる。 doWithSpring、doWit…
※この記事はGrails 2.4.2をベースに記述しています 一見簡単にみえるが、意外と奥が深い。 次のようなドメインクラスがあったとする。 class Person { String username static constraints = { username unique: true } } この時、デフォルトのスキャフォル…
パスワードをハッシュで保存して置くのは当たり前ですが、レインボーテーブル使用した総当たり探索の対策として、ソルトとストレッチングを組み合わせ、より安全にパスワードを保存するのが一般的になってきました。 GrailsのSpring Security Core Pluginは…
Struts1のEOLがアナウンスされました。 最後のリリースから長く時間が経過しており、実質開発は終了している状態でしたが、このタイミングでのアナウンスとなりました。 アナウンスの中では、次の乗り換え先として、Struts2・Spring Web MVC・Grails・Stripe…
Ruby、Railsの世界では、プレーンテキストで記述できる受け入れテストツールとして有名なCucumberですが、Pure-Javaで実装されたcucumber-jvmのお陰で、Grailsでもプラグインをインストールすることで簡単にcucumberが利用できるようなります。 準備 cucumbe…
元ネタ Grailsではgrails-app/serviceディレクトリ配下などにクラスを置くと自動的にSpringのbeanとして認識されますが、src/groovyやsrc/javaといったディレクトリでは自動的にはbeanとして登録されません。 src/groovy、src/java配下のクラスをbeanとして…
LiquibaseではchangeSetにcontext属性が設定できます。このcontext属性を使用することで、実行時に適用するchangeSetの範囲を指定できます。 databaseChangeLog = { changeSet(author: "yamkazu", id: "default-ctx") { ... } changeSet(author: "yamkazu", …
runAlways属性をtrueに設定することで毎回実行するchangelogを定義できます。runOnChange属性がtrueの場合ではchangesetのチェックサムが変更になった時のみ実行しますが、runAlways属性をtrueにするとチェックサム変更有無に関係なく毎回実行してくれます。…
既存のデータが存在する場合に、NotNull制約が付与されたカラムを追加する場合は少し工夫が必要です。単にカラムを追加すると既存のデータがNULLになってしまうためエラーとなります。これを回避するには一度NotNull制約を付与せずにカラムを追加し、既存デ…
Database Migration PluginではLiquibaseで使用可能なchangesetのコマンドが、groovyフォーマットのchangesetでも同様に使用可能になっています。 使用可能なコマンドの一覧はLiquibaseのリファレンスを参照してください。 今日はこの中からCustom SQLとCust…
データベースへの反映履歴を管理するdatabasechangelogテーブルにはmd5sumというchangesetのチェックサムを格納するカラムがあります。 liquibaseのリファレンスには以下のように記述されています。 LiquiBase が変更セットに到達すると、MD5Sum を計算して…
どうも見つからない。いろいろ探してたらorg.hibernate.criterion.LikeExpressionなるものを発見したがorg.hibernate.criterion.Exampleで使われているくらいで他に使われていない。なんぞこれ。とりあえず、これを使おう。LikeExpressionはコンストラクタが…
前回の続きDatabase Migration Pluginのすごいところはロールバックが出来る事。ロールバックを行うコマンドは主に3つ種類がある。 dbm-rollback-count dbm-rollback-to-date dbm-rollback それぞれ個別に見ていく。 dbm-rollback-count dbm-rollback-count…
ずっと放置していたけどDatabase Migration Pluginを触ってみた。やばい。これは使わないと。実際にアプリケーションを作りながら説明してく。とりあえずプロジェクトを作成。 $ grails create-app database-migration-test 作成したらBuildConfig.groovyを…
いまだにprintfデバッグを卒業出来ません。そんなことはどうでもよくてリモートデバッグしてみる。山本さんの http://d.hatena.ne.jp/mottsnite/20120705/1341495778 に書いてあるとおり2.1からデバッグする際は-debugオプションを使ったほうが良いとのこと…
元ネタ 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が追加されています。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(…
http://grails.org/plugin/cache がgrails 2.1からデフォルトでインストールされています。実態としてはSpringのCache Abstractionを薄くラップしたような形です。Serviceのメソッドや、Controller、またはGSPのレンダリングをキャッシュできます。メソッド…
元ネタ http://compiledammit.com/2012/08/16/custom-json-marshalling-in-grails-done-right/有名な話なのかもしれませんが、独自Marshaller登録できるんですね。知らなかった。GrailsではJSONレスポンス書き出し方に代表的な2つのやり方が存在します。 ht…
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…
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…
ドメイン間の関連の型をどの様に設定するかでの挙動の違いです。リファレンスに書いてあることですが、いろいろ動かしながら検証してみました。ログとかだらだら長くて見にくいですが、面白いので貼り付けときました。Bookドメイン class Book { String titl…
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:…
参考 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…
grails2.1.0での情報。org.codehaus.groovy.grails.validation.AbstractConstraint#rejectValueWithDefaultMessageで処理している。 ... final Locale locale = LocaleContextHolder.getLocale(); final Class constrainedClass = (Class) args[1]; final St…
リファレンスの内容そのままですが、同じ項目群を複数持つだとか、DB上の項目が多いからグルーピングしたいといった時にコンポジションが使えます。この場合テーブル上は1テーブルで表現されますが、アプリケーション側からは対応するクラスに分割して扱えま…
GORMでの継承によってデータベース上でどのようにスキーマ定義するかというお話です。Grailsのデフォルトの継承戦略はtable-per-hierarchyになっています。例えば次のようなドメインがあったとします。 class Parent { String name } class Sub1 extends Par…
こういうやつです。それぞれがひとつのNodeというインスタンスで表される。 class Node { String name static belongsTo = [parent: Node] static hasMany = [children: Node] static mappedBy = [children: "parent"] } belongsToとhasManyしてしてマッピン…
デフォルトだとtest-appした際に標準出力は、どこかいずこへもっていかれコンソールに表示されません。ちょっとした機能確認の為にUnitTestを使って学習テストなどやっていると、ついついprint使いたくなってしまうのですが、なぜかコンソールに出力してくれ…
DataSource.groovyでloggingSqlをtrue、formatもしたい場合はformatSqlをtrueに。 dataSource { ... loggingSql = true formatSql = true } おなじDataSource.groovyで hibernate { show_sql = true format_sql = true ... } としても同じ。こんな感じで出る…