S2Daoは以下のDBに対応しています。
これら以外のDBでも、基本的なSELECT・INSERT・UPDATE・DELETEが使え、LEFT OUTER JOIN構文をサポートしているDBでしたら動作すると思います。
プロシージャ呼び出しについての対応状況はDBに異なるので、S2Daoのドキュメント http://s2dao.seasar.org/ja/ を確認してください。
S2サポーター (2006-04-29 (土) 19:48:55)
Question
S2Daoの開発の中で、updateBatchを投げる際、更新したくない列を指定
したいのですが、方法がわかりません。
Answer
NO_PERSISTENT_PROPSアノテーションを使用すると更新対象に含まれなくなります。
http://www.seasar.org/s2dao.html#NoPersistentPropsAnnotation
を参照されると良いと思います。
参考投稿
http://ml.seasar.org/archives/seasar-user/2005-November/000360.html
http://ml.seasar.org/archives/seasar-user/2005-November/000361.html
S2サポーター (2006-04-29 (土) 19:46:22)
Question
S2DAOでconnectionPoolを利用しているのですが、コネクションのプーリングが
行なわれていないような動作をしているので、設定に漏れがあるのではないかと
思い、何かアドバイスを頂ければとメールさせて頂きました。
実行ログを見ると、最初に1件のみ
[物理的なコネクションを取得しました]を表示して、以降はDBにアクセスする
と[論理的なコネクションを取得しました]と出力され、1つ物理コネクションを
使い回しているようなログが出力されています。
この時に、Oracleのv$sessionを見ると論理的なコネクションの数だけセッショ
ンが張られています。
しばらくDBへのアクセスを行なわずにいるとログには[論理的なコネクション
を取得しました]の表示がOracleに張られていたセッションの数だけ表示されま
す。(この時、Oracelのセッションも開放されています)
利用しているSeasarのバージョン
Seasar2.2.10
S2DAO1.0.28
以下のように設定を行なっているのですが、何か過不足がありますでしょうか?
---[j2ee.dicon]---------------------------------- <?xml version="1.0" encoding="Shift_JIS"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN" "http://www.seasar.org/dtd/components.dtd"> <components namespace="j2ee.dicon"> <component name="transactionManager" class="org.seasar.extension.jta.TransactionManagerImpl"/> <component name="requiredTx" class="org.seasar.extension.tx.RequiredInterceptor"/> <component name="requiresNewTx" class="org.seasar.extension.tx.RequiresNewInterceptor"/> <component name="mandatoryTx" class="org.seasar.extension.tx.MandatoryInterceptor"/> <component class="org.seasar.extension.jdbc.impl. BasicResultSetFactory"/> <component class="org.seasar.extension.jdbc.impl. BasicStatementFactory"/> <component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl"> <property name="driverClassName"> "oracle.jdbc.driver.OracleDriver" </property> <property name="URL"> "jdbc:oracle:thin:@192.168.0.5:1521:white" </property> <property name="user">"serverwatcher"</property> <property name="password">"serverwatcher"</property> </component> <component name="connectionPool" class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl "> <property name="timeout">600</property> <property name="maxPoolSize">10</property> <destroyMethod name="close"/> </component> <component name="dataSource" class="org.seasar.extension.dbcp.impl.DataSourceImpl"/> </components> -------------------------------------------------------[dao.dicon]-------------------------------------- <?xml version="1.0" encoding="Shift_JIS"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN" "http://www.seasar.org/dtd/components.dtd"> <components namespace="dao"> <include path="j2ee.dicon"/> <component class="org.seasar.dao.impl.DaoMetaDataFactoryImpl"/> <component name="interceptor" class="org.seasar.dao.interceptors.S2DaoInterceptor"> <aspect>dao.requiredTx</aspect> </component> </components> ----------------------------------------------------Answer
原因は ServerControllerの constructorにありますね。
S2Containerを要求ごとに diconファイルから構築しているので、結局のとこ
ろVM空間上に複数のコンポーネントセットが存在することになります。
ということは、DataSourceもConnectionPoolも複数あるので、ログにあるよう
な動きになります。
S2の挙動というよりかは、DIの適用パターンにあわせて設計・動きを少し変更
されたほうがよろしいかと思います。
私なら以下の方法を使います
1. EditLogic が xxxDao を使う(必須)のであれば EditLogicのコンストラ クタに引数を追加し、default constructorを削除する。 これは public EditLogic(xxxDao dao) { this.dao = dao; } のようにする 2. EditLogicは diconに定義する(か、自動登録されるような規則に従った 上でAutoRegisterを使う) これでEditLogicのインスタンス管理はコンテナのもとにあります 3. EditLogicが必要な部分は S2を経由してインスタンスを取得するように します。たとえば、EditLogicが StrutsのActionなのであれば S2Struts を用います. new EditLogic() している場所を getComponent(EditLogic.class) のよ うにすればいいかと思いますが、この方法を用いるのであればインタフェー スと実装クラスに分離したほうが良いです。 (S2JSFの場合は特に意識する必要すらないと思います)
参考投稿
http://ml.seasar.org/archives/seasar-user/2005-November/000446.html
http://ml.seasar.org/archives/seasar-user/2005-November/000481.html
S2サポーター (2006-04-29 (土) 19:42:46)
Question
S2DAO、S2JDBC等でSQLを発行する際にコンパイル済みのSQLを発行するのか、
毎SQLを生成して発行するのか、どちらなのでしょう?サンプルのログをみてい
ると毎回生成しているように思えるのですが。。。
Answer
PreparedStatementに格納してあるプリコンパイルされたSQLを発行しています。
ログではき出されているSQLは、Statementに渡される(発行する)SQLを
そのまま表示している訳ではなく、ログにはき出すためにS2が、パラメータが
埋め込まれたSQLをせっせと作っています。
org.seasar.extension.jdbc.impl.BasicHandlerクラスの
getCompleteSqlメソッドが参考になると思います。
http://www.seasar.org/websvn/filedetails.php?repname=s2container&path=%2Ftrunk%2Fseasar2%2Fs2-extension%2Fsrc%2Fmain%2Fjava%2Forg%2Fseasar%2Fextension%2Fjdbc%2Fimpl%2FBasicHandler.java&rev=0&sc=0
参考投稿
http://ml.seasar.org/archives/seasar-user/2005-November/000431.html
http://ml.seasar.org/archives/seasar-user/2005-November/000452.html
S2サポーター (2006-04-29 (土) 19:40:26)
Question
S2DaoでJDK1.4.2_08だと動くコードがJDK1.4.2_10にして
Daoのメソッドを呼ぶとClassCastExceptionでこけてしまうコードがあります。
DaoのメソッドはBigDecimalを返すメソッドで引数4つを取ります。public BigDecimal sumTest(String a, String b, String c, String d, String e); public static final String sumTest_ARGS = "a,b,c,d";
SQLファイルはselect sum(qty) from testdat s left outer join xx l on s.hoge = l.hoge and s.hoge2 = l.hoge2 where s.a = /*a*/'a' and s.b = /*b*/'b' and s.c = /*c*/'0' and l.d = /*d*/'1'
となっています(フィールド名等はサンプルです)
スタックトレースはjava.lang.ClassCastException at sun.nio.cs.ext.JISAutoDetect$Decoder.decodeLoop(Unknown Source) at sun.nio.cs.ext.JISAutoDetect$Decoder.decodeLoop(Unknown Source) at java.nio.charset.CharsetDecoder.decode(Unknown Source) at sun.nio.cs.StreamDecoder$CharsetSD.implRead(Unknown Source) at sun.nio.cs.StreamDecoder.read(Unknown Source) at java.io.InputStreamReader.read(Unknown Source) at java.io.BufferedReader.read1(Unknown Source) at java.io.BufferedReader.read(Unknown Source) at java.io.Reader.read(Unknown Source) at org.seasar.framework.util.ReaderUtil.readText(ReaderUtil.java:27) at org.seasar.framework.util.TextUtil.readText(TextUtil.java:18) at org.seasar.dao.impl.DaoMetaDataImpl.setupMethod(DaoMetaDataImpl.java:132) at org.seasar.dao.impl.DaoMetaDataImpl.setupSqlCommand(DaoMetaDataImpl.java:112) at org.seasar.dao.impl.DaoMetaDataImpl.<init>(DaoMetaDataImpl.java:103) at org.seasar.dao.impl.DaoMetaDataFactoryImpl.getDaoMetaData(DaoMetaDataFactoryImpl.java:42) at org.seasar.dao.interceptors.S2DaoInterceptor.invoke(S2DaoInterceptor.java:34) at org.seasar.framework.aop.impl.NestedMethodInvocation.proceed(NestedMethodInvocation.java:26) at org.seasar.framework.aop.interceptors.TraceInterceptor.invoke(TraceInterceptor.java:33) at org.seasar.framework.aop.impl.NestedMethodInvocation.proceed(NestedMethodInvocation.java:26) at org.seasar.framework.aop.interceptors.InterceptorChain.invoke(InterceptorChain.java:24) at test.TestDatDao$$EnhancedByS2AOP$$18622f3$$MethodInvocation$$sumTest5.proceed(MethodInvocationClassGenerator.java) at test.TestDatDao$$EnhancedByS2AOP$$18622f3.sumTest(TestDatDao$$EnhancedByS2AOP$$18622f3.java)
となっております。
SQLを組み立てる時にこけている様な感じです。
DAOのバージョンはs2-dao-1.0.28.jarでPostgreSQL8.0.3を使っております。
JDKの違いやdaoのバージョンで何か注意する点等ありますでしょうか?
Answer
JDK 1.4.2_10にはJISAutoDetectのバグがあります。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=25802&forum=12
FIXされるまで1.4.2_10より前のバージョンを使われることをオススメします。
参考投稿
http://ml.seasar.org/archives/seasar-user/2005-November/000429.html
http://ml.seasar.org/archives/seasar-user/2005-November/000430.html
S2サポーター (2006-04-29 (土) 19:33:05)
Question
S2Daoのプライマリーキーの処理について伺います。
S2Daoを使ってDB2へのアクセスを勉強しております。
テーブルにプライマリーキーが設定していないと、S2Daoが
「・・にプライマリーキーが見付りません」の例外を投げてきます。
当然テーブルに直接プライマリーキーが設定していれば問題が
ありませんが、既存のテーブルに明示的に主キーではなく、
Index(索引)の形で主キーを指定されていることです。
この場合はS2Daoをどのようにすれば
「・・にプライマリーキーが見付りません」の例外を回避できるのでしょうか。
Answer
UPDATEやDELETEなどの自動生成を行わなければ、プライマリキー
がなくても問題ありません。
したがって、UPDATEやDELETEをsqlファイルやsqlコメントで行えば
例外を回避できると思います。
参考投稿
http://ml.seasar.org/archives/seasar-user/2005-October/000626.html
http://ml.seasar.org/archives/seasar-user/2005-October/000632.html
S2サポーター (2006-04-29 (土) 19:30:14)
Question
j2ee.diconでの設定を利用すれば自動的に1個のコネクションを得られます。
複数DBとのコネクションを取得するにはどうすればよいのでしょうか。
Answer
まず,j2ee.dicon をコピーして DB 接続ごとの dicon ファイルを
作成してください.
例えば ds1.dicon
<components namespace="ds1"> <include path="j2ee.dicon"/> <component name="dataSource" class="..."> ・・・ </component> <component name="xaDataSource" class="..."> ・・・ </component> <component name="connectionPool" class="..."> ・・・ </component> </component>
必要なコンポーネントは 3 つだけです.
transactionManager 等のコンポーネントは削除してください.
同じように ds2.dicon も作成します.
そして j2ee.dicon から name 属性が以下の値になっている<component> 要素を削除します.
dataSource
xaDataSource
connectionPool
ds1.dicon で記述したコネクションを使用するコンポーネント用の
dicon は ds1.dicon をインクルードします.
例えば app1.dicon<components namespace="app1"> <include path="ds1.dicon"/> ・・・ <components>
ds2.dicon で記述したコネクションを使用するコンポーネント用の
dicon は ds2.dicon をインクルードします.
例えば app2.dicon
<components namespace="app2"> <include path="ds2.dicon"/> ・・・ <components>
もし,ds1.dicon と ds2.dicon に記述したコネクションを同時に
使用するコンポーネントがある場合は,両方をインクルードして
コンポーネントのプロパティに明示的に DataSource を設定します.
例えば app3.dicon
<components namespace="app3"> <include path="ds1.dicon"/> <include path="ds2.dicon"/> <component name="..." class="..."> <property name="dataSource1">ds1.dataSource</property> <property name="dataSource2">ds2.dataSource</property> ・・・ </component> ・・・ </components>
最後に,app1.dicon や app2.dicon,app3.dicon 等を app.dicon に
インクルードします.
<components> <include path="app1.dicon"/> <include path="app2.dicon"/> <include path="app3.dicon"/> ・・・ </components>
実際に確認していないので間違いがあるかもしれませんが,
だいたいこんな感じでできるかと思います.
参考投稿
S2サポーター (2006-04-29 (土) 19:26:23)
Question
複雑なSQLを処理する場合の実装方法について教え頂けませんでしょうか?
Answer
引数の値をSQL文に文字列として直接埋め込む。ドキュメントの
「埋め込み変数コメント」を参照。
参考投稿
http://ml.seasar.org/archives/seasar-user/2005-December/000288.html
http://ml.seasar.org/archives/seasar-user/2005-December/000301.html
S2サポーター (2006-04-29 (土) 18:45:30)
Question
s2daoを使用して、PostgresSQLの幾何データ型を扱っているのですが、
PostgresSQLがサポートしている幾何データ演算子の中には
?# のように「?」を含む演算子があります。
例:select A.name from road as A, road as B where A.path ?# B.path and
B.name = 'hoge';
この演算子を使用したSQLを発行しようとすると、「?」がバインド変数とみなされ
て、
java.sql.SQLExceptionが発生してしまいます。
ログで実行されたSQLをみてみると、
select A.name from road as A, road as B where A.path null# B.path and B.name
= 'hoge';
となっています。
org.seasar.framework.util.PreparedStatementUtilで
java.sql.PreparedStatementを使用している以上、
s2daoでPostgresSQLの幾何データ演算子を使用することはできないのでしょうか?
ちなみに、単独でjava.sql.Statementを使用して同じSQLを発行すると、
正常に問い合わせが行われました。
何かよい方法があれば、教えてください。
よろしくお願い致します。
Answer
CREATE OPERATOR文を使用して、新しく作成したOPERATORの中でpath_interを
呼び出すことで、無事解決することができました。
参考投稿
http://ml.seasar.org/archives/seasar-user/2006-January/000175.html
http://ml.seasar.org/archives/seasar-user/2006-January/000176.html
http://ml.seasar.org/archives/seasar-user/2006-Janu
ドキュメントに
IN /*引数名*/(...)
とあるように、
IN /*dto.aaa*/('aaa')
というふうにコメントより後ろの括弧が必要。
JDBC APIから知る方法が無いため、無理。
Question
SQLのパラメータ?の部分に、以下のような文字列が入ってしまいます。
WHERE USER./*searchKey*/USER_ID LIKE /*searchValue*/'%t%' ↓↓↓↓↓↓↓ WHERE USER.'s2.dao.user.UserPagerCondition@1b35125' LIKE 's2.dao.user.UserPagerCondition@1b35125'
Answer
Dao側が
public List findUserByDto(UserPagerCondition dto);
である場合には、SQL側を
USER./*dto.searchKey*/USER_ID LIKE /*dto.searchValue*/'%t%'
のように"dto"を付けてみて頂けますか?
排他制御には、TimestampよりもVersionNoの方が良い。 レコード更新時の時間を持ちたいのならば、トリガーを使うのが良いのでは。