[YMIR-284] Page/DTOクラスでString型以外(Dateなど)を定義して変換エラー時にnullになる Created: 2009-01-19  Updated: 2009-02-02  Resolved: 2009-01-27

Status: Closed
Project: Ymir
Component/s: ymir-core
Affects Version/s: 1.0.0
Fix Version/s: 1.0.1

Type: Improvement Priority: Major
Reporter: jflute Assignee: skirnir
Resolution: Fixed Votes: 0
Labels: None


 Description   

【概要】
ドキュメント見ると仕様のようだが、
この動きはユーザにはつらい。
http://ymir.seasar.org/docs/1.0.x/ref/typeConversion

【環境】
Mac OS X
Safari
Java 5.0

【解決案】
<1>
変換エラーしたことをログに出力

<2>
Integerなら、Setterに@Numericを自動的に付与する。

Dateなら、Setterに@Datetimeを自動的に付与する。
フォーマットはZPTで書いてあるyyyy%mm%ddの定義を
@Datetimeのpatternにそのまま利用する。

【補足】
「1」だけでも今よりは良くはなるが、
実際には「2」ぐらいのフォローがないと、
String型以外の型をプロパティとして定義するやり方は現実的でない。



 Comments   
Comment by skirnir [ 2009-02-02 ]

確認ありがとうございました。closeとします。

Comment by jflute [ 2009-01-27 ]

> 変換エラーのログ
も確認できました。
とても良いログなのでユーザもこれなら困らないでしょう。
ありがとうございます。

[DateConverter#doConvert():25}] - Conversion error occured. You may add a constraint annotation to the corresponding property in order to notify validation error to a user: aaa 
java.text.ParseException: Unparseable date: "aaa"
	at java.text.DateFormat.parse(Unknown Source)
        ...
Comment by jflute [ 2009-01-27 ]

Conversationの件は、確認しました。ありがとうございます。

変換エラーのログは、まだ確認出来ていません。
Maven2化して、最新SNAPSHOTが反映されていないだけかもしれません。
またコメントします。

Comment by skirnir [ 2009-01-27 ]

おっしゃる問題(Conversationから復元された値のフォーマットが不適切)に対処しました。ZPTでプロパティ名だけを書いたTAL式でフォーマットが効いていなかったのが原因でした。

また、変換エラーのログを出力するようにしました(r2709)。

これでこのissueに関する対処を完了しました。確認をお願いします。

Comment by jflute [ 2009-01-26 ]

まず、「tal:define=」でDTOを作るべきでないということで、
formのnameを使ってDTOを作ったところ、
検索ボタンを押した後の再描画で「2008/12/12」と表示されました。
ありがとうございます。

ZPT上の書き方も指摘通りこのようにしました。

<input type="text" name="birthdate" tal:attributes="value birthdate"/>

続いて、別の画面から戻ってきたときやページングでの自分へのリダイレクト時に
Conversationから値を復元して表示する場合は、「2008-12-12 00:00:00」と表示されて
しまいました。いずれも「_get」での処理です。
同様に編集入力画面で初回表示の「_get」で検索した値を表示する場合も同じ現象です。
(原因も同じではないかと考える)

Comment by jflute [ 2009-01-26 ]

試しに、Extendedでのオーバーライドを消して、
Baseのプロパティ定義に直接「@Datetime("yyyy/MM/dd")」を
付けてやってみましたが、結果は変わらずでした。ふむぅ...

Comment by jflute [ 2009-01-26 ]

こちら「dbflute-ymir-example」で再現します。
https://www.seasar.org/svn/sandbox/dbflute/trunk/dbflute-ymir-example

会員検索一覧(/member/search/list.html)の検索条件「正式会員日」に
試しに「2008/12/12」と入力して検索ボタンを押した後の再描画で、
「2008-12-12 00:00:00」と表示されてしまいます。

<table border="1" tal:define="cond self/condition">
...(略)

// 「正式会員日」
<input type="text" name="formalizedDateFrom" class="T_date" size="14" tal:attributes="value cond/formalizedDateFrom"></input>
// 「PageクラスのBase」
    @org.seasar.ymir.annotation.Meta(name="formProperty",value="condition")
    public java.util.Date getFormalizedDateFrom() {
        return this.condition.getFormalizedDateFrom();
    }

    @org.seasar.ymir.annotation.Meta(name="formProperty",value="condition")
    @org.seasar.ymir.scope.annotation.RequestParameter
    public void setFormalizedDateFrom(java.util.Date formalizedDateFrom) {
        this.condition.setFormalizedDateFrom(formalizedDateFrom);
    }
// 「PageクラスのExtended」
    @Override
    @RequestParameter
    @Datetime("yyyy/MM/dd")
    public void setFormalizedDateFrom(Date formalizedDateFrom) {
        super.setFormalizedDateFrom(formalizedDateFrom);
    }
// 「Dto」
    public void setFormalizedDateFrom(java.util.Date formalizedDateFrom) {
        this.formalizedDateFrom = formalizedDateFrom;
    }

> freyja-1.0.12-20090122.161429-2.jar
> ymir-zpt-1.0.1-20090122.163401-5.jar
classpathも再度確認しましたが、この通りです。
WEB-INF/lib配下に古いバージョンは含まれてないことも確認しました。

Comment by skirnir [ 2009-01-26 ]

こちらでは@Datetime("yyyy/MM/dd")をSetterにつけて正しく動作しているようなので、すみませんが今度現象の詳細を確認させて下さい。

Comment by jflute [ 2009-01-24 ]

SNAPSHOT試してみました。

freyja-1.0.12-20090122.161429-2.jar
ymir-zpt-1.0.1-20090122.163401-5.jar

Setterに@Datetimeを付けない状態でのDate型プロパティは、
対称性が保たれていることを確認しました。

Setterに@Datetimeを付けた状態でのDate型プロパティは、
対称性が保たれていません。
具体的には、@Datetime("yyyy/MM/dd")をSetterに付与して、
画面で「2007/12/12」を入力してPostbackしたら、
再描画時は「2007-12-12 00:00:00」と表示されました。
再度Postbackするとバリデーションエラーです。

Comment by jflute [ 2009-01-23 ]

ありがとうございます。
内容も問題ないと思います。

Comment by skirnir [ 2009-01-23 ]

そうですね、ではログを出力するようにします。

具体的には、Conversionに失敗した場合に「Conversionに失敗した」ということと、「Constraintがないと変換エラーが起きてもアプリ利用者にフィードバックできないのでConstraintをつけてね」ということをログ出力する感じで考えたいと思います。

Comment by jflute [ 2009-01-23 ]

> DateについてはString→Date変換と同じ日付パターンで表示されるようにしました。
ありがとうございます!。
これでフォーマット定義が冗長化することがなくなります。

> 自動生成時に型を見てconstraint annotationを付与することは可能ではありますが、生成→ユーザが手動でconstraintを変更→再生成
そうですね。
ZPTで書いたフォーマットが自動生成時にPageクラスのBaseに自動で反映されるとかであれば、
フォーマット変更時もZPTを修正して再自動生成とできますが、Pageクラスのものをユーザが
手動で直すとなるとややこしいですね。

Constraintが定義されるまでは「Constraintがないよ」という
ログが出力されてユーザが検知できれば自動でContraint付与はとりあえず
なくてもいいかなと思います。

Comment by skirnir [ 2009-01-23 ]

<2>でDateの際にZPT中のパターンを見るという意見がありましたが、これの代わりにプロパティに制約が付与されていない場合のプロパティの入出力の対称性を高めました。

対称性とは、あるプロパティのGetterが返すオブジェクトがHTMLに埋め込まれる場合の文字列表現と同じ文字列がリクエストパラメータとして渡されてきた場合、それがそのプロパティのSetterによって設定されるということを意味します。現状ではStringやIntegerについては対称性が保たれていますが、Dateについてはそうなっていません。

そこで、DateについてはString→Date変換と同じ日付パターンで表示されるようにしました。これでDateについても対象性が保たれることになります。さらに、Setterに@Datetimeでパターンが指定されている場合はそのパターンに従ってDateを文字列に変換して表示するようにしました。

一方、自動生成時に型を見てconstraint annotationを付与することは可能ではありますが、生成→ユーザが手動でconstraintを変更→再生成、とした場合にユーザが手動で変更したconstraintを残して追加でconstraintを生成しないということが難しい(単にもともとある場合に生成しないようにするだけだと、生成→型を変更→再生成、とした場合に以前のものが残ってしまう)ため、対応するかは考えさせて下さい。

Comment by jflute [ 2009-01-21 ]

Exampleポリシーとしては、Date型は使わないようにしてますが、
Integerはちょっと使いたくなると思うので、「2」があるととてもうれしいです。

そういう意味では「2」も優先度はIntegerのが高いです。

Comment by skirnir [ 2009-01-21 ]

まず、Ymirの型変換の挙動は、基本的にこの世界のデファクトスタンダードであるStrutsの型変換の挙動に合わせてあります。そのため変換エラー時は何もしないという挙動にしています。

ただ、<1>ログに出力したいというニーズは理解します。また、<2>型に対応するconstraintを自動的に付与するというアイデアは良いと思いますので、ともに検討します。

Generated at Sun Mar 16 23:43:34 JST 2025 using Jira 9.17.5#9170005-sha1:a31f12538a5bc5fbd519064b86500f26fb9312c1.