bekkou68 の日記

Gogengo! や IT 技術など。

selectBySqlFile() するとパスの頭に "META-INF/sql/" が付加されて ResourceNotFoundException になる - When selectBySqlFile() Then "META-INF/sql/" Added to Prefix of Path and ResourceNotFoundException Occurred

前提 - Condition

使用している SAStruts は「sa-struts-1.0.4-sp6.zip」、S2-Tiger は「s2-tiger-2.4.39.jar」。
SAStruts which I uses is "sa-struts-1.0.4-sp6.zip" and S2-Tiger is "s2-tiger-2.4.39.jar".

実装 - Implementation

Service をこのように実装した。
I implemented Service as follows.

public class EntityService extends AbstractService<Entity> {
    public List<Entity> findEntity() {
        /* I'd like to execute "project/entity/Entity/findEntity.sql" */
        return selectBySqlFile(Entity.class, "findEntity.sql").getResultList();
    }
}
public abstract class AbstractService<ENTITY> extends S2AbstractService<ENTITY> {
}

現象 - Phenomenon

以下のエラーが発生する。パスの頭に "META-INF/sql/" が付加される。
The following error is occurred. "META-INF/sql/" was added to a prefix of path.

[ESSR0055]リソース(META-INF/sql/project/entity/Entity/findEntity.sql)が見つかりません

原因 - Cause

S2AbstractService.java のコンストラクタで呼ぶ setEntityClass() がパスの頭に "META-INF/sql/" を付加していた。
setEntityClass() which is called by the constructor of S2AbstractService.java added "META-INF/sql/" to the prefix of path.

public abstract class S2AbstractService<T> {
    protected void setEntityClass(Class<T> entityClass) {
        this.entityClass = entityClass;
        sqlFilePathPrefix = "META-INF/sql/"
                + StringUtil.replace(entityClass.getName(), ".", "/") + "/";
    }
}

対策 - Countermeasure

S2AbstractService.java のサブクラスであり、全 Service のスーパークラスである AbstractService.java で setEntityClass() を "META-INF/sql/" が付加されないようにオーバーライドした。問題は解決した。
I overrode setEntityClass() of AbstractService.java which is a sub class of S2AbstractService.java and is a super class of all Services not to add "META-INF/sql/". The problem was solved.

public abstract class AbstractService<ENTITY> extends S2AbstractService<ENTITY> {
    @Override
    protected void setEntityClass(Class<ENTITY> entityClass) {
        this.entityClass = entityClass;
        sqlFilePathPrefix = StringUtil.replace(entityClass.getName(), ".", "/") + "/";
    }
}

疑問1 - Question 1

アドホックな感じがするのだけど対策は何がベストなのだろうか? 設定ファイルを変更すれば直せるというオチとかはないのだろうか?
I think it is very ad-hoc, what is the best countermeasure? Can I solve the problem by just modifying some configuration files?

疑問2 - Question 2

公式は、SQL ファイルを配置するパッケージを「ルートパッケージ.entity.エンティティ名」と推奨している。
The official recommends a package which located SQL files as "[rootPackage].entity.[entityName]".

SQLファイルは、クラスパス上にあるならどこにおいてもかまいませんが、 ルートパッケージ.entity.エンティティ名 のパッケージに対応したディレクトリ配下に置くことを推奨します。 例えば、 Employeeに関するSQLファイルは、 examples/entity/Employee ディレクトリにおくと良いでしょう。

Seasar2 - S2JDBC - JdbcManager - SQLファイルによる操作


なぜ META-INF 配下にしたのだろうか? 素直に推奨パッケージを使えないのが疑問。
Why they changed to META-INF? The question is that I can't use the recommended package straightforward.

Revision 3931 - (view) (annotate) - [select for diffs]
Modified Tue Sep 30 16:36:06 2008 JST (16 months, 2 weeks ago) by higa
File length: 7988 byte(s)
Diff to previous 3929

[CONTAINER-260]S2AbstractServiceで使うSQLファイルをMETA-INFの下におくようにしました。
s2container Log of /trunk/s2-tiger/src/main/java/org/seasar/extension/jdbc/service/S2AbstractService.java - The Seasar Project Repository Browser


−ω− 使いこなすのが難しい……。