Hibernate/JPA 利用者にはおなじみの概念を、MongoDB GORM で実現するための Tips 。
参考
Mapped Superclass の実現
利用シーン
- 具象エンティティのデータのみを作成する
- 抽象クラスは、DB上でも抽象的位置づけである(データを持たない)
Example
grails-app/domain/AbstractUser.groovy
abstract class AbstractUser {
static mapWith = "mongo"
static mapping = {
name index: true
}
static constraints = {
desc nullable: true
}
String name
String desc
def beforeInsert() {
doSomething()
}
def afterLoad() {
doSomething()
}
}
grails-app/domain/User.groovy
class User extends AbstractUser {
static mapWith = "mongo"
static mapping = {
order index: true
}
static constraints = {
lastLoginDate nullable: true
}
int order
Date lastLoginDate
}
特徴
- indexの継承: OK
ただし、ensureIndexが実行されるのでabstractUserコレクションは作成されてしまう
AbstractUserにmapWith = "none"
を記述するとコレクション作成を抑制できるが、mapWith = "mongo"
指定している User も強制的に除外されるので利用できない - constraintsの継承: OK
- beforeInsertの継承: OK
- afterLoadの継承: OK
注意事項
- どちらも grails-app/domain 下に置く
src/groovy 下では動作しない - バージョンによっては以下の事象に注意。
Update is not working when properties of concrete class changed - 具象エンティティのプロパティのみが変更された場合に、エンティティが dirty 状態に遷移しない。
(抽象エンティティのプロパティが変更された場合は遷移する)
Polymorphic associations
利用シーン
-
User.list()
やActiveUser.count()
のように、エンティティごとにクエリを発行したい場合
Example
grails-app/domain/User.groovy
class User {
static mapWith = "mongo"
}
grails-app/domain/ActiveUser.groovy
class ActiveUser extends User {
}
grails-app/domain/InactiveUser.groovy
class InactiveUser extends User {
}
特徴
- ドキュメントプロパティに以下のような型情報が追加される
"_class": "ActiveUser",
注意事項
- どちらも grails-app/domain 下に置く
src/groovy 下では動作しない - 親エンティティ(上の例では User)が abstract だと期待する動作をしない
(save時に_class
プロパティが入らない、またロードも正常に行えない)
collection per class hierarchy
利用シーン
- Hibernate/JPA の「table per class hierarchy」的な。
Example
grails-app/domain/User.groovy
class User {
static mapWith = "mongo"
static mapping = {
collection "user"
}
}
grails-app/domain/ActiveUser.groovy
class ActiveUser extends User {
static mapping = {
collection "activeUser" // 無視される
}
}
grails-app/domain/InactiveUser.groovy
class InactiveUser extends User {
static mapping = {
collection "inactiveUser" // 無視される
}
}
特徴
- ドキュメントプロパティに以下のような型情報が追加される
"_class": "ActiveUser",
- 子クラスの collection 指定は無視され、全て user コレクションに保存される
注意事項
- どちらも grails-app/domain 下に置く
src/groovy 下では動作しない - 親エンティティ(上の例では User)が abstract だと期待する動作をしない
(save時に_class
プロパティが入らない、またロードも正常に行えない)