Showing posts with label Grails. Show all posts
Showing posts with label Grails. Show all posts

2008/11/11

G2One join SpringSource


This is the biggest of today.

在报道里,Rod说:

SpringSource plans to integrate Grails with dm Server, the company's OSGi-based open-source Java server that uses the Spring Framework and launched this year.
当然还包括
Groovy would let enterprise programmers re-use their existing Java skills while Groovy programmers can tap underlying power of Java. Groovy is able to access Java class libraries and the Spring container, which is used in the dm Server and can run on the Java virtual machine (JVM).

首先是祝贺G2One,当然还有Guillaume LaForgeGraeme Rocher。当然,两个人都看到了这次收购对于Groovy和Grails的好的一面,两个人都提到Eclipse IDE得支持。应该可以这么猜测,不久会有一个相当不错的Groovy和Grails Eclipse IDE(应该来自Spring的IDE team)。

其他么,大家都重视不免有些担心这次收购会对这两个Java Open Community的明星项目略微担心,毕竟前些日子SpringSource的maintainence policy风波还未完全平息

2008/09/21

Scala smooths ORM and more

Two Scala features', object as module and implicit convert, can greatly ease your daily hibernate coding.

I do love the ORM module (GORM) provided Grails, which allow you to be focus on plain domain classes and these domain classes get enhanced later on by the container(Grails). So your plain domain classes (or POGOs) automatically have functionality of presist, such as save, delete, and queries.

Grails implements this by a lot of complicated Groovy MOP tricks(1,2). Basically, once such a protocol is defined, it is carried by domain classes along whole life cycle. Even your domain object is not currently working under persist layer, it still has save and delete method. This might not be a big deal in most cases. However, dynamic methods cost great much, it rings the bell about performance issue.

Implementing such feature in current Java programming work is also not good. Usually, such kind of framework-supported-enhancement involves lots of bytecode enhancement or instance proxying related reflection. Framework like ActiveObjects enhances your domain classes using the latter approach(correct me if I am wrong). As a result, you are not be able to create your domain instance using new keyword (your domain classes are enhanced hence changed). You have to create domain instance using a factory method provided by framework. It is faster, but break your POJOs in this or that ways. Your thin domain class will have this or that new injected methods or properties which might break even serialization.

So, how Scala implicit conversion do about this? My answer is implicit conversion and object as modules. Say I have a domain class Book which is implemented as following Scala code (you can do this in Java also).


import org.edgebox.orm.Entity
import scala.reflect.{BeanProperty=>BP}
class Book extends Entity{
@BP
var id=0L
@BP
var name:String = null
@BP
var price = 0
// other properties are omitted for simplicity
}

Later on when you use this domain class in your persist layer, you can simply do following:

import org.edgebox.orm.ORM
import org.edgebox.orm.Query._

class APersistService(val orm:ORM){
import orm._
def aPersistMethod = {
val Book = classOf[Book]
// doing query
Book.all.filter(ilike("name", "scala")).order(asc("price")).fetch
// doing get by id
val book = Book.get(1)
// update book ...
book.save
//...
}
}
The query syntax is stolen from Google AppEngine (or Django).

Quite simple, the trick is the import orm._ clause. You can treat instance orm as a module, the import clause introduces all elements of that orm instance into this PersistService. The orm instances has two interesting implicit convert functions:


type EntityType = T forSome{ type T <: Entity}
implicit def entityWrapper(e:EntityType) = new RichEntity
implicit def entityTypeWrapper(et:Class[_<:Entity])= new RichEntityType

So, when you tries to call book.save although your domain class knows nothing about persistence, the persist module (orm instance) and implicit conversion can nicely handle this for you, automatically and transparently by Scala compiler.

Benefits?
  1. You keep your domain class clean, no one is gonna inject anything into your domain class or intercept any calls during your operations;
  2. Very minor performance overhead, you gotta no performance lose when you are working with your domain class and very minor performance overhead when you are trying to using specific layer-related method;
  3. Object as module also bring flexibility; instance of orm can be configured using various possibility and also Spring-enabled;
  4. The most interesting point is (which is also my most favorite part), this approach introduces a more clean and flexible design onto multi-layered system. You can focus your domain class but when working on different layer you just need to import different function modules which automatically enhance your domain classes with layer-specific function. For example, our domain class might be able to do serialization by calling book.toJson or book.toRdf under layer handling Restful representation. And using which kind of serialization is totally relied on a simple import clause.
You can find above sample code under http://svn.assembla.com/svn/edgebox/edgebox/branch/edgebox/, under package org.edgebox.orm. At current moment, this toolkit is tightly based on Spring and Hibernate (as Grails does).

Updates


The code of RichEntityType and RichEntity are:

class RichEntityType[T](val self:Class[T], val dao:Dao[T]) extends Proxy{
def get(id:Serializable)={
dao.get(id)
}
}

class RichEntity[T<:Entity](val self:T, val dao:Dao[T]) extends Proxy{
def save()={
dao.save(self)
self
}
}

Footer

  © Blogger template 'Grease' by Ourblogtemplates.com 2008

Back to TOP