12

私はこの抽象クラスを持っています:

DomainItem

abstract public class DomainItem {

    @DatabaseField(generatedId = true)
    protected long id;

    @ForeignCollectionField(eager = false)
        protected ForeignCollection<ContentItem> contentItens;

    //getters and setters
}

ContentItem:

abstract public class ContentItem {

    @DatabaseField(generatedId = true)
    protected long id;

    @DatabaseField(foreign = true)
    protected DomainItem domainItem;


    @DatabaseField()
    protected String content;

    //getters and setters
}

そしてこれら(要約なし):

@DatabaseTable()
public class PhytoterapicItem extends DomainItem{

    public PhytoterapicItem(){

    }

}

PhytoterapicContent

@DatabaseTable(tableName = "phytoterapiccontent")
public class PhytoterapicContent extends ContentItem {

    @DatabaseField(canBeNull = false)
    private String defaultName;

    @DatabaseField(canBeNull = false)
    private String scientificName;

    //getters and setters
}

DatabaseHelperで、テーブルを作成しようとしています。

//DatabaseHelper
...
@Override
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
    try {
        Log.i(TAG, "onCreate");
        TableUtils.createTable(connectionSource, PhytoterapicContent.class);
        Log.i(TAG, "Created table PhytoterapicContent");

        TableUtils.createTable(connectionSource, PhytoterapicItem.class);
        Log.i(TAG, "Created table PhytoterapicItem");
    catch{
       ...
    }

テーブルPhytoterapicContentが作成されます。しかし、次のエラーが発生しました。

java.sql.SQLException:フィールド'contentItens'列名の外部コレクションクラスbr.com.project.model.ContentItemに、クラスbr.com.project.model.PhytoterapicItemの外部フィールドが含まれていません

4

2 に答える 2

12

ドキュメント( http://ormlite.com/docs/foreign-collection )からこの重要なブロックに気付く/理解するのに少し時間がかかりました:

ForeignCollectionフィールドがある場合、コレクション内のクラス(この例ではOrder)には、コレクションを持つクラス(この例ではAccount)の外部フィールドが必要であることに注意してください。アカウントに外国の注文のコレクションがある場合、注文にはアカウントの外国のフィールドが必要です。ORMLiteが特定のアカウントに一致する注文を見つけることができるようにするために必要です。

私が混乱した理由は、「含まれているクラス」がコレクションを持つクラスを参照しているサンプルコード(ドキュメントまたはサンプルプロジェクト)が見つからなかったためです。それは口頭で説明されていますが、関係の性質を考えると、最初の数回それを見るとき、説明に従うのは少し難しいかもしれません。

上記の元の質問(私が偶然見つけた解決策を試すというアイデアを最終的に得た方法)にリストされているように、以下のブロック例は、OrmLiteで1対多のコレクション関係をマップする正しい方法のようです。

さらに、コレクション所有者クラスをコレクション要素クラスに設定する方法についての注意事項があります。


世話をする主な手順は次のとおりです。

A.コレクション(この場合はDomainItem )を持つクラスで、コレクションフィールドに次のように注釈を付けます。

@ForeignCollectionField(eager = true)

B.コレクション(この場合はContentItem )に含まれるクラスでは、コレクションを含む親クラスへの明示的な参照が必要です。

@DatabaseField(foreign = true) protected DomainItem domainItem;

C. ContentItemを永続化する前に、外部キーをDomainItemに戻すために、DomainItemをそのContentItemに保存する必要があります。

curContentItem.setDomainItem(curDomainItem);

contentItemDao.create(curContentItem);`

私のコレクションが最初に取得されていなかったときに、これを理解しました。ContentItemのテーブルを調べましたが、DomainItem_idがそこに設定されていませんでした。

例:

public class DomainItem {

    @DatabaseField(generatedId = true)
    protected long id;

    @ForeignCollectionField(eager = false)
    protected ForeignCollection<ContentItem> contentItens;

    // ...
}


public class ContentItem {

    @DatabaseField(generatedId = true)
    protected long id;

    @DatabaseField(foreign = true)
    protected DomainItem domainItem;

    public void setDomainItem(DomainItem domainItem) {

       this.domainItem = domainItem;
    }
}
于 2014-04-25T17:35:34.917 に答える
11

したがって、例外メッセージはここで役立つように設計されています。クラス名を削除して引用するには:

ContentItemフィールドcolumn-nameの外部コレクションクラスにクラスcontentItensの外部フィールドが含まれていませんPhytoterapicItem

それが事実のようです。がある場合は常にForeignCollection、コレクションに含まれるクラスには、親クラスに戻る外部フィールドが必要です。

あなたの場合、オブジェクトのを持っているクラスをPhytoterapicItem拡張します。つまり、タイプが外部フィールドである必要があります。それ以外の場合、ORMLiteは、テーブル内のどのアイテムが特定のに関連付けられているかをどのように知るのでしょうか。DomainItemForeignCollectionContentItemContentItemPhytoterapicItemContentItemPhytoterapicItem

外部コレクションのドキュメントにあるオブジェクトの例はAccount、スキーマに役立つ場合があります。それぞれにオブジェクトの外部コレクションがあります。特定のに対応するオブジェクトのコレクションを見つけるために、別のクエリをクエリするたびに実行されます。つまり、それぞれに異物が必要です。OrderAccountOrderAccountOrderAccountOrderAccount

于 2012-04-23T20:19:45.950 に答える