カスタム検索

2008年3月11日火曜日

GrailsでHibernate+C3P0のpooling

Grailsでpoolingをする場合、grails-app/conf/DataSource.groovy の pooled = true にしてやる事で pooling されるようですが、
これはHibernateのbuilt-in poolingを使っている(?)気がします。

で、built-in poolingは
Using Hibernate built-in connection pool (not for production use!)
ということで、本番では推奨されていません。

ここでHibernateが対応しているサードパーティのpoolingの出番です。
C3P0とApache DBCPとProxoolが使えるらしいのですが、今回はC3P0を使います。

grails-app/conf/spring/resources.xml というファイルを作成し、以下のように設定します。


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass"><value>oracle.jdbc.OracleDriver</value></property>
<property name="jdbcUrl"><value>jdbc:oracle:thin:@127.0.0.1:1521:orcl</value></property>
<property name="user"><value>username</value></property>
<property name="password"><value>password</value></property>
</bean>
</beans>


driverClassとjdbcUrlはDBに合わせて調整して下さい、今回はOracleへ接続しています。
resources.xmlを記述する事で DataSource.groovy の driverClass などは無視されます。

ここで一つ注意事項です。
C3P0では use_second_level_cache と use_query_cache を true にしてやる必要があります。

DataSource.groovy に以下を追加します。


hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='org.hibernate.cache.EhCacheProvider'
}


追加しなかったり、falseにしても普通に動作してしまったりするのですが、環境によりエラーが出るので true にしておくのが良いみたいです。

2008年3月3日月曜日

OracleとCLOBとGrailsと

OracleのCLOB型はデフォルトでDISTINCT出来なくなっています(パフォーマンスの問題?)
なのでGrailsからクエリを直接実行しようとした場合は注意が必要です。
DISTINCTしなければいいのかというと、そういうわけでもなく、 like は使えるが = は使えないという非常に微妙な状態になります。(Oracle8ではlikeもNGっぽいです)
以下にテストした結果、OKなケースとNGなケースをまとめます。

以下の形のドメインクラス

class Book {
Author author
String title
}


class Author {
static mapping = {
clob type:'text'
}

String clob
}


以下のクエリを実行します。

SELECT DISTINCT a from Author as a // NG

from Author as a WHERE a.clob like '%Clob%' // OK

from Author as a WHERE a.clob = '%Clob%' // NG

SELECT DISTINCT b from Book as b WHERE b.author.clob like '%Clob%' // OK

SELECT DISTINCT b from Book as b WHERE b.author.clob = 'Clob' // NG


Oracleが嫌いになりました :p