Friday, October 31, 2008

New GORM Features Coming in 1.1

Now that The Definitive Guide to Grails 2nd Edition (barring a few reviews) is a wrap, I've been refocusing in Grails development. First up, is GORM and we've implemented a number of great improvements including:

Better GORM events

Previously, GORM supported beforeInsert, beforeUpdate and beforeDelete events, now there is afterInsert, afterUpdate and afterDelete to complete the picture

Persistence of Collections of Basic Types

GORM now supports persisting basic types like String, Integer and so on using a join table:
class Person {
static hasMany = [nicknames:String]
}
Improvements to Data Binding

It is now simpler to bind data to a subset of properties. Previously you could use the syntax:
person.properties = params
Which would bind all the incoming request parameters to the person. If you didn't want that behavior you could use the bindData method. Now you can bind to a subset of properties using the subscript operator:
person.properties["firstName","lastName"] = params
And access a subset of the domain classes properties using the same syntax:
person.properties["firstName","lastName"].each { println it }
Read-Only Access to Objects

Persistent instances can now be loaded in a read-only state using the read method:
def book = Book.read(1)
Default Sort Order

Associations can now be sorted using a default sort order declared at the class level:
class Book {
String title
static mapping = {
sort "title"
}
}
Or at the association level:
class Author {
static hasMany = [books:Book]
static mapping = {
books sort:"title"
}
}
Batch Fetching

GORM now supports configuring batch fetching (an optimization of lazy loading) using the ORM DSL at the class level:
class Book {
String title
static mapping = {
batchSize 15
}
}
Or at the association level:
class Author {
static hasMany = [books:Book]
static mapping = {
books batchSize:15
}
}
Improvements to Dynamic Finders

There is a new InList suffix that can be used with dynamic finders:
def groovyBooks = Book.findByAuthorInList(['Dierk Koenig', 'Graeme Rocher'])
Dynamic finders can also now use the query cache:
def books = Book.findByTitle("Groovy in Action", [cache:true] )
And upgrade to a pessimistic lock:
def books = Book.findByTitle("Groovy in Action", [lock:true] )
Legacy Mapping for Many-to-Many and Unidirectional One-to-manys

Many-to-many and Unidirectional One-to-many associations can use the joinTable argument to alter the way they map to the underlying database:
class Book {
String title
static belongsTo = Author
static hasMany = [authors:Author]

static mapping = {
authors joinTable:[name:"mm_author_books", key:'mm_book_id' ]
}
}
class Author {
String name
static hasMany = [books:Book]
static mapping = {
books joinTable:[name:"mm_author_books", key:'mm_author_id']
}
}

19 comments:

  1. Anonymous10:38 am

    Awesome improvements Graeme, I especially like the improvements to mass assignment. Much more elegant. Looking forward to 1.1

    ReplyDelete
  2. Congrats on the Wrap of book. I am really looking forward to it.

    The enhancements sounds great! I look forward to the code being released.

    GORM is very nice functionality, . . . Any possibility that it will be a Groovy module in the near future?

    ReplyDelete
  3. @jim

    It will always be part of the Grails project. We will be making it possible to use standalone (outside of Grails), of course you will have to add dependencies such as Spring, Hibernate and some Grails jars to use it.

    ReplyDelete
  4. Anonymous1:27 pm

    For the "Read-Only Access to Objects", Book.read(1), are there read-only equivalents to findBy* methods?

    ReplyDelete
  5. These new features will be awesome, especially the mapping of String & primitive-type lists.
    Will the new ed of DGG cover 1.1 or is it based on 1.0.x ?

    ReplyDelete
  6. @prpatel The new book covers Grails 1.1, so yes these features are covered

    @anonymous No not currently, the reason is the Hibernate criteria API doesn't have a setReadOnly method as the Query object does. Shocking omission really

    ReplyDelete
  7. Very nice! In particular I really like that pessimistic locking stuff. I suspected you would round out the hibernate events and I am very happy to see the new DSL syntax to describe join tables. Really looking forward to 1.1!

    ReplyDelete
  8. how about the "standalone GORM"?

    ReplyDelete
  9. Anonymous10:52 am

    "Many-to-many and Unidirectional One-to-many associations can use the joinTable argument to alter the way they map to the underlying database:"

    I thought this was an existing feature.

    ReplyDelete
  10. @flyisland Yes standalone GORM is coming

    @anonymous Yes it worked with many-to-manys but not with unidirectional one-to-manys

    ReplyDelete
  11. Anonymous12:19 pm

    "def groovyBooks = Book.findByAuthorInList(['Dierk Koenig', 'Graeme Rocher'])"

    What if Authors have more than one String property? Which one is chosen?

    Wouldnt it be more expressive to write:

    def books = Book.findByAuthor(name:['Dierk König','Graeme Rocher'])

    ReplyDelete
  12. @anonymous The example assumes that "author" is a String:

    String author

    ReplyDelete
  13. Grails is awesome.

    I haven't heard much talk about JRubyOnRails compared with Grails. But I've come to the conclusion that if a shop has an existing Oracle/JDK1.4/etc (which is many places in D.C.) environment, Grails is a better fit.

    ReplyDelete
  14. Anonymous9:42 am

    Haha, about that subscribe thingy for bindDate... Exactly what i needed. Great :) In the meantime i stick with that solution:

    http://twitter.com/rotnroll666/status/1032993242

    ReplyDelete
  15. Graeme, can you add a new feature on GORM to get the error message.

    before we have to use messageSource and locale to get the message (as string).

    ReplyDelete
  16. Anonymous2:59 pm

    搬家 搬家 搬家公司 搬家 搬家 票貼 借款 徵信社 徵信 補習班 多益 留學 在職進修 婚紗 補正下着 新娘秘書 汽車旅館 室內設計 室內設計 中古車買賣 植牙 坐月子 婚禮佈置 催眠 派報 漆彈 視訊會議 真空成型 Shade sail nike shoes MBA 在职研究生 在职博士 關鍵字廣告 租屋 花蓮民宿 花蓮民宿 花店 花店 花蓮民宿 租房子 xo醬 牛軋糖 牛嘎糖 代償 房屋貸款 信用貸款 失眠 減肥 糖尿病 日立家電 外遇 離婚 抓姦 外遇蒐證 外遇抓姦 侵權 仿冒 應收帳款 工商徵信 徵信 徵信社 外遇 徵信 徵信社 外遇 电动隔膜泵 自吸泵 化工泵 离心泵 磁力泵 螺杆泵 水泵 隔膜泵 气动隔膜泵 白蟻 花蓮民宿 美國留學 新娘秘書 汽車旅館 新娘秘書 催眠 花蓮民宿 搬家 搬家服務 搬家保障 搬家網 搬家估價 徵信 徵信的意義 徵信服務 徵信報導 徵信問答 徵信知識 婚禮佈置 婚禮佈置 http://www.life13.com 票貼 工作服 班服 團體服 糖尿病 勞工體檢 呼吸照護 資源回收 生日禮物 美國遊學 留學代辦 彩妝造型 新娘秘書 宜蘭民宿推薦 催眠 漆彈場 太陽能熱水器 減重 自助洗衣加盟 綠豆椪 床墊 創業加盟 資源回收 鋼戒 廢車回收 創業加盟 龍眼蜜 買房子 買房子 班服配件 團體服配件 團體服 班服 團體服 班服 團體服 眼鏡 創業加盟 室內設計公司 室內設計公司 室內設計公司 最好的婚禮佈置,婚禮佈置花園感官花園婚禮佈置,婚禮佈置最新消息,婚禮佈置專業多元化,為你量身定作完美婚禮佈置,完美的婚禮佈置請來感官花園。婚禮佈置時間雙休請來電預約,婚禮佈置周五正常營業。婚禮佈置地點遼寧街,婚禮佈置聯絡方式電話。婚禮佈置訂購方式,婚禮佈置請提前兩天通知,婚禮佈置請先完成付款及傳真或郵件傳送匯款單。婚禮佈置免費外送價格,婚禮佈置請參考列表。

    ReplyDelete