[Seasar-user:14724] Re: [dbflute]idの自動採番について

kubo [E-MAIL ADDRESS DELETED]
2008年 6月 17日 (火) 10:33:21 JST


久保です。

植田さん、おはようございます。

> 抽象TestCaseで「現在のテーブルに入っているIDのMAXをsetval()」する方法で
> テストを行い、現象を回避することが出来ました。
> ReplaceSchemaで作成しているテストデータも同じように、教えて頂いた方法を
> 真似させてもらいます。ありがとうございます。

良かったです。ご報告ありがとうございます。
ReplaceSchemaも利用されているのですね。
(すいませんドキュメントレスで。。。)
わからないことがあったらまた聞いて下さい。

2008/6/17 Chihiro Ueta <[E-MAIL ADDRESS DELETED]>:
> 久保様、おはようございます。
>
> 植田です。お世話になります。
> ご丁寧に教えて頂き、本当にありがとうございます。
>
>> S2TestCase#readXlsReplaceDb()は利用しておりませんが、
>> DBFluteのReplaceSchemaを利用してテストデータを投入して
>> いて、全く同じ現象が発生しました。
>>> 「現在のテーブルに入っているIDのMAXをsetval()」
>> する処理をreadXlsReplaceDb()を実行したときに
>> 一緒に実行されるように仕掛けることで回避できるかと思います。
>> S2TestCaseを継承したそのプロジェクト独自の抽象TestCaseを
>> 作成し、そこでこの処理を入れるのが良いかと思います。
>
> 抽象TestCaseで「現在のテーブルに入っているIDのMAXをsetval()」する方法で
> テストを行い、現象を回避することが出来ました。
> ReplaceSchemaで作成しているテストデータも同じように、教えて頂いた方法を
> 真似させてもらいます。ありがとうございます。
>
>> はい、これに関しては、PostgreSQLのserial型は特別扱いで
>> Sequence設定を省略できるようにしてあるだけなので、
>> 明示的に設定しても特に何も変わりません。
>> http://dbflute.sandbox.seasar.org/contents/dbvendor/postgresql.html
>
> すみません。上記、確認しました。
>
> 以上、宜しくお願い致します。
>
> kubo さんは書きました:
>> 久保です。
>>
>> 植田さん、こんばんは
>>
>> 下記の件、自分も悩んだことがあります。
>>
>> S2TestCase#readXlsReplaceDb()は利用しておりませんが、
>> DBFluteのReplaceSchemaを利用してテストデータを投入して
>> いて、全く同じ現象が発生しました。
>>
>> 1. replace-schema.batを実行
>> 1-1. playsql/replace-schema.sqlでCreateTable&Sequence
>> 1-2. playsql/data配下のデータが登録される
>> →ここではSequence利用しないで登録(1,2,3,4,5...)
>>
>> 2. JUnitからinsert()
>> →Sequenceが1から始まるので例外
>>
>> 自分は、この手順の中に
>> 「現在のテーブルに入っているIDのMAXをsetval()」
>> する処理を含めて回避できました。
>>
>> 1. replace-schema.batを実行
>> 1-1. playsql/replace-schema.sqlでCreateTable&Sequence
>> 1-2. playsql/data配下のデータが登録される
>> →ここではSequence利用しないで登録(1,2,3,4,5...)
>> 1-3. playsql/take-finally.sqlでsetval() {★}
>> →「現在のテーブルに入っているIDのMAXをsetval()」
>> →テストデータ投入後に実行される(take-finally.sql)
>>
>> 2. JUnitからinsert()
>> →SequenceがMaxの次から始まるので正常動作
>>
>> そのplaysql/take-finally.sqlは実際にこれです。
>>
>> // DBFlutePostgreSQLExample
>> https://www.seasar.org/svn/sandbox/dbflute/trunk/dbflute-postgresql-example/dbflute_exampledb/playsql/take-finally.sql
>>
>> select setval('member_member_id_seq', (select max(member_id) from member));
>> select setval('member_login_member_login_id_seq', (select
>> max(member_login_id) from member_login));
>> select setval('product_product_id_seq', (select max(product_id) from product));
>> select setval('purchase_purchase_id_seq', (select max(purchase_id)
>> from purchase));
>>
>> ※serial型のSequenceを利用しています。
>>
>>
>> このように
>> 「現在のテーブルに入っているIDのMAXをsetval()」
>> する処理をreadXlsReplaceDb()を実行したときに
>> 一緒に実行されるように仕掛けることで回避できるかと思います。
>> S2TestCaseを継承したそのプロジェクト独自の抽象TestCaseを
>> 作成し、そこでこの処理を入れるのが良いかと思います。
>>
>> (もしくは、手間でなければテストデータを100万台から
>> 始めるというのも手です。テストを100万回実行しない限り
>> 落ちることはないはずです。が、ちょっと気持ち悪い気もします)
>>
>>> 「work」のテーブルの ID のカラムは SERIAL8 で作成し、Sequence設定は行っ
>>> ておりません。
>>> 試しにSequence設定で以下のような設定を行いましたが、insert時に振られるID
>>> はやはり 1 から始まりました。
>>
>> はい、これに関しては、PostgreSQLのserial型は特別扱いで
>> Sequence設定を省略できるようにしてあるだけなので、
>> 明示的に設定しても特に何も変わりません。
>> http://dbflute.sandbox.seasar.org/contents/dbvendor/postgresql.html
>>
>>
>> 2008/6/16 Chihiro Ueta <[E-MAIL ADDRESS DELETED]>:
>>> 植田と申します。
>>> いつもお世話になっております。
>>>
>>> dbfluteのインサート時のIDの自動割り当てについて質問させてください。
>>>
>>> 以下のような環境で使用させて頂いております。
>>> DB:PostgreSQL8.1
>>> jdbc:8.3-603.jdbc3
>>> dbflute:0.7.1
>>> s2-framework:2.4.24
>>> s2dao:1.0.47
>>>
>>> S2Unitで、S2TestCase#readXlsReplaceDb("エクセルファイル") を利用したテス
>>> トを行っております。
>>> 「work」のテーブルのテストを行うためにエクセルファイルには、ID(primary
>>> key)が 1 から 5 までのテストデータを「work」のテーブルに登録しておりま
>>> す。テストには「work」テーブルの外部参照テーブルを含めたいため、エクセル
>>> ファイルにはID(primary key)も指定しております。
>>> 「work」テーブルに対してdbfluteのWorkBhv#insertのテストを実行した場合
>>> に、ID が 1 から始まってしまうため、下のようなプライマリキーが重複してい
>>> るというエラーが発生します。この場合のテストを成功させるために、何か良い
>>> 方法はないでしょうか?設定内容などについて注意点などが御座いましたらご助
>>> 言頂けませんでしょうか?
>>>
>>> --------エラー内容--------
>>> org.seasar.framework.exception.SQLRuntimeException: [ESSR0072]SQLで例外
>>> (SQL=[INSERT INTO work ("省略") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
>>> ?, ?, ?, ?, ?, ?)], Message=[[ESSR0072]SQLで例外(SQL=[INSERT INTO work
>>> ("省略") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)],
>>> Message=[0], ErrorCode=23505, SQLState={3})が発生しました : [SQLで例外
>>> (Message=[ERROR: duplicate key violates unique constraint "work_pkey"],
>>> ErrorCode=0, SQLState=23505)が発生しました。], [ERROR: duplicate key
>>> violates unique constraint "work_pkey"], ErrorCode=0, SQLState=23505)が
>>> 発生しました
>>> --------------------------
>>>
>>> 再度テストを実行すると、自動で割り当てられるIDは 2 になります。
>>> これを繰り返すと、IDは1づつ大きくなっていき、6 になったときにテストに成
>>> 功します。
>>>
>>> 「work」のテーブルの ID のカラムは SERIAL8 で作成し、Sequence設定は行っ
>>> ておりません。
>>> 試しにSequence設定で以下のような設定を行いましたが、insert時に振られるID
>>> はやはり 1 から始まりました。
>>>
>>> dfprop/sequenceDefinitionMap.dfprop
>>>
>>> map:{
>>>    ; work     = work_id_seq
>>> }
>>>
>>> 以上、宜しくお願い致します。
>>>
>>> _______________________________________________
>>> Seasar-user mailing list
>>> [E-MAIL ADDRESS DELETED]
>>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>>
>> _______________________________________________
>> Seasar-user mailing list
>> [E-MAIL ADDRESS DELETED]
>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>
>>
>>
>
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user
>


Seasar-user メーリングリストの案内