使用Foreign Collection Field创建表

Mun*_*nir 12 java ormlite foreign-collection

我有这个抽象类:

DomainItem

abstract public class DomainItem {

    @DatabaseField(generatedId = true)
    protected long id;

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

    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

ContentItem:

abstract public class ContentItem {

    @DatabaseField(generatedId = true)
    protected long id;

    @DatabaseField(foreign = true)
    protected DomainItem domainItem;


    @DatabaseField()
    protected String content;

    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

这些(没有摘要):

@DatabaseTable()
public class PhytoterapicItem extends DomainItem{

    public PhytoterapicItem(){

    }

}
Run Code Online (Sandbox Code Playgroud)

PhytoterapicContent

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

    @DatabaseField(canBeNull = false)
    private String defaultName;

    @DatabaseField(canBeNull = false)
    private String scientificName;

    //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

在我的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{
       ...
    }
Run Code Online (Sandbox Code Playgroud)

表PhytoterapicContent已创建.但我得到了以下错误:

java.sql.SQLException:字段'contentItens'column-name的外部集合类br.com.project.model.ContentItem不包含类br.com.project.model.PhytoterapicItem的外部字段

Gen*_* Bo 12

我花了一段时间才注意到/从文档(http://ormlite.com/docs/foreign-collection)中了解这个关键块:

请记住,当您有一个ForeignCollection字段时,集合中的类必须(在此示例中为Order)必须具有包含该集合的类的外部字段(在此示例中为Account).如果Account有一个外国的Orders集合,那么Order必须有一个Account外部字段.这是必需的,因此ORMLite可以找到与特定帐户匹配的订单.

我之所以感到困惑的原因是因为我没有找到任何示例代码(在文档或示例项目中),其中"包含的类"引用带有集合的类.它是口头描述的,但考虑到关系的性质 - 对于某些描述,我认为在前几次看到它时可能会有些棘手.

正如上面原始问题中所列出的那样(这是我最终想到尝试我偶然发现的解决方案的想法),下面的示例块似乎是在OrmLite中映射一对多集合关系的正确方法.

此外,还有一个关于如何将集合持有者类设置到集合元素类中的说明.


以下是需要注意的主要步骤:

A.在具有集合的类(本例中为DomainItem)中,以这种方式注释集合字段:

@ForeignCollectionField(eager = true)

B.在集合中包含的类(本例中为ContentItem)中,您必须具有对包含集合的父类的显式引用:

@DatabaseField(foreign = true) protected DomainItem domainItem;

C.在持久化ContentItem之前,必须将DomainItem保存到该ContentItem,以便将外键设置回DomainItem:

curContentItem.setDomainItem(curDomainItem);

contentItemDao.create(curContentItem);`
Run Code Online (Sandbox Code Playgroud)

当我最初没有检索到我的收藏时,我想到了这一点.我查看了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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Gra*_*ray 11

所以异常消息旨在帮助这里.引用删除的类名称引用它:

ContentItem字段contentItenscolumn-name的外部集合类不包含类的外部字段PhytoterapicItem

看起来就是这样.无论何时ForeignCollection,集合包含的类必须具有返回父类的外部字段.

在你的情况,PhytoterapicItem延长了DomainItem它具有类ForeignCollectionContentItem对象.这意味着ContentItem必须具有类型的外来字段PhytoterapicItem.否则,ORMLite如何知道ContentItem表中的哪些项与特定项相关联PhytoterapicItem.

外部集合文档中的示例AccountOrder对象可以帮助您使用模式.每个都有一个外来的对象集合.每当您查询单独的查询时,都会执行查找与特定对象相对应的对象集合.这意味着每个人都必须有一个异物.AccountOrderAccountOrderAccountOrderAccount