Grails で GORM と同一の Connection を使用する

Grails で GORM に使用している Connection を、GORM以外で使用する方法を記します。

サンプルソースはGithubに公開しています。

 

// 2013/06/08 追記 ---------------------------------------

コメントにいただいた方法で書きなおしてみました。

// --------------------------------------------------------

 

■何が問題?

以下のソースの場合、DIしたSqlManager の Connection と、GORMで使用している Connection が異なるため、count2(DI)とcount3(GORM)が異なる値となります。

insert.sql がコミットされるのは#update が終わってからなので、count3はレコード追加前の件数となります。

// -------------------------------------------------------------------  

class CustomerService {

    SqlManager sqlManager

    def update() {
        int count = sqlManager.getCount("com/area_b/samples/select.sql")

        sqlManager.executeUpdate("com/area_b/samples/insert.sql")

        int count2 = sqlManager.getCount("com/area_b/samples/select.sql")
        int count3 = Customer.count
    }
}

// -------------------------------------------------------------------  

ちょっと困ったちゃんですよね。

 

■GORMで使用しているConnectionを取り出す。

以下のような感じで、取り出すことができます。

// -------------------------------------------------------------------  

import jp.sf.amateras.mirage.SqlManager
import jp.sf.amateras.mirage.SqlManagerImpl
import jp.sf.amateras.mirage.dialect.Dialect
import jp.sf.amateras.mirage.provider.ConnectionProvider
import jp.sf.amateras.mirage.provider.DefaultConnectionProvider
import org.hibernate.SessionFactory
import org.hibernate.connection.ConnectionProvider as SCP
import org.hibernate.engine.SessionFactoryImplementor

class CustomerService {

    MySQLDialect dialect
    def sessionFactory

    def update() {

        SqlManager manager = createInstance(sessionFactory, dialect)

        int count = manager.getCount("com/area_b/samples/select.sql")

        manager.executeUpdate("com/area_b/samples/insert.sql")

        int count2 = manager.getCount("com/area_b/samples/select.sql")
        int count3 = Customer.count
    }

    SqlManager createInstance(SessionFactory sessionFactory, Dialect dialect) {
        SessionFactoryImplementor sfi = (SessionFactoryImplementor) sessionFactory
        SCP scp = sfi.getConnectionProvider()
        ConnectionProvider connectionProvider = new DefaultConnectionProvider()
        connectionProvider.connection = scp.connection
        SqlManager manager = new SqlManagerImpl()
        manager.connectionProvider = connectionProvider
        manager.dialect = dialect
        return manager
    }
}

// -------------------------------------------------------------------  

もっと良い方法がありそうな気もしますが、とりあえずの目標は達成!