1

オブジェクトの 1 つで定義した多対多のプロパティに where 句を追加しようとしています。列が存在しないという休止状態のエラーが発生し続けるため、何か間違ったことをしているに違いありません。

テンプレート cfc で:

<cfproperty
    name="Settings"
    fieldtype="many-to-many"
    cfc="Setting"
    linktable="settings_templates"
    fkcolumn="templateID"
    inversejoincolumn="settingsId"
    where="deleted='false'"
>

設定 cfc で:

<cfproperty
    name="templates"
    fieldtype="many-to-many"
    cfc="Template"
    linktable="settings_templates"
    fkcolumn="settingsId"
    inversejoincolumn="templateID"
    where="deleted='false'"
>

私が得ているエラーは次のとおりです。

08/02 16:06:27 [jrpp-170] HIBERNATE ERROR - [Macromedia][SQLServer JDBC Driver][SQLServer]無効な列名 'deleted'。

誰かが私が間違っていることを見ることができますか? 両方のテーブルに削除された列がありますが、リンク テーブルにはありません。

4

2 に答える 2

1

where多対多のプロパティの動作は非常に奇妙です...

これをデバッグするには、Hibernate のログ記録を有効にします。この投稿を参照してください: http://www.rupeshk.org/blog/index.php/2009/07/coldfusion-orm-how-to-log-sql/

次の例を見てください。

記事.cfc

/**
 * @output false
 * @persistent true
 * @table article
 */
component {

    property name="id" fieldtype="id";
    property name="title";

    property 
        name="tags" singularname="tag" 
        fieldtype="many-to-many" cfc="Tag" linktable="link_article_tag" fkcolumn="articleId" 
        inversejoincolumn="tagId" where=" deleted = 0 "
    ;

}

タグ.cfc

/**
 * @output false
 * @persistent true
 * @table tag
 */
component {

    property name="id" fieldtype="id";
    property name="name";
    property name="deleted" dbdefault="0";

    property 
        name="articles" singularname="article" 
        fieldtype="many-to-many" cfc="Article" linktable="link_article_tag" fkcolumn="tagId" 
        inversejoincolumn="articleId"
    ;

}

このようなすべての記事をリストしようとするとormExecuteQuery('from Article')、休止状態のログに何が追加されているかを確認してください。

select
    tags0_.articleId as articleId6_1_,
    tags0_.tagId as tagId1_,
    tag1_.id as id0_0_,
    tag1_.name as name0_0_,
    tag1_.deleted as deleted0_0_ 
from
    link_article_tag tags0_ 
inner join
    tag tag1_ 
        on tags0_.tagId=tag1_.id 
where
    tags0_.deleted = 0 

くそっ!なんてこった:| tags0_ == テーブルに参加 ... 何が問題なのかわかりますか?

この動作を理解するために、次のファイルを使用して Application.cfc で HBMXML 生成を有効にthis.ormSettings.saveMapping = true します。

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class entity-name="Tag" lazy="true"
        name="cfc:www.app.models.test.Tag" table="tag">
        <id name="id" type="string">
            <column length="255" name="id"/>
        </id>
        <property name="name" type="string">
            <column name="name"/>
        </property>
        <property name="deleted" type="string">
            <column default="0" name="deleted"/>
        </property>
        <bag name="articles" table="link_article_tag">
            <key column="tagId"/>
            <many-to-many class="cfc:www.app.models.test.Article" column="articleId"/>
        </bag>
    </class>
</hibernate-mapping>

わかること:where属性はbagto ではなく、レベルで設定されていますmany-to-many。このように編集すると:

    <bag name="tags" table="link_article_tag">
        <key column="articleId"/>
        <many-to-many class="cfc:www.app.models.test.Tag" column="tagId" where=" deleted = 0 "/>
    </bag>

生成された SQL は次のようになります。

select
    tags0_.articleId as articleId62_1_,
    tags0_.tagId as tagId1_,
    tag1_.id as id59_0_,
    tag1_.name as name59_0_,
    tag1_.deleted as deleted59_0_ 
from
    link_article_tag tags0_ 
inner join
    tag tag1_ 
        on tags0_.tagId=tag1_.id 
where
    tag1_.deleted = 0 

この方法は機能しますが、コードのメンテナンスと可読性には適していません。誰かがより良い解決策を持っているなら、私は興味があります。

于 2012-08-02T08:59:01.897 に答える
1

これまでのところ、これを回避する唯一の方法は、を使用してゲッターをオーバーライドすることORMExecuteQuery()です。そこで、オブジェクトを直接クエリして、このようなものを探すことができます。個人的には、cfscript で作業する方が好きなので、コードは次のようになります。

public array function getSettings() {
    return ORMExecuteQuery("SELECT s FROM template t JOIN t.settings s WHERE t.id=:id AND s.deleted=:deleted", {
        deleted=false, id=this.getId()
    });
}

NB – テストされていない例

もちろん、私が持っているようにパラメーターを使用する必要はありませんを使用することもできますが、それはdeleted=falseあなた次第です (私は個人的にパラメーターを使用するのが好きです)。

singularNameまた、多対多プロパティの属性を忘れないでください。

関連して、両方のオブジェクトでプロパティを使用する際に問題が発生しました。この場合、実際にはテンプレート オブジェクトでのみ使用する必要があります。このように考えてみてください: テンプレートはその設定を知る必要がありますが、設定はそれが属するテンプレートを知る必要はありません。このように両方のオブジェクトのプロパティを使用すると、場合によってはエラーが発生する可能性があります。

于 2014-04-02T19:22:36.450 に答える