使用Foreign Collection Field创建表

时间:2012-04-23 20:13:44

标签: 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
}

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'column-name的外部集合类br.com.project.model.ContentItem不包含类br.com.project.model.PhytoterapicItem的外部字段

2 个答案:

答案 0 :(得分:12)

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

  

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

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

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

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


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

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

@ForeignCollectionField(eager = true)

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

@DatabaseField(foreign = true) protected DomainItem domainItem;

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

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;
    }
}

答案 1 :(得分:11)

因此异常消息旨在提供帮助。引用删除的类名称引用它:

  

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

看起来就是这样。只要你有ForeignCollection,集合所包含的类必须将一个外部字段返回给父类。

在您的情况下,PhytoterapicItem扩展了DomainItem类,其ForeignCollectionContentItem个对象。这意味着ContentItem必须具有PhytoterapicItem类型的外部字段。否则,ORMLite如何知道表格中哪个ContentItem项与特定PhytoterapicItem相关联。

foreign collection documentationAccountOrder个对象的示例可以帮助您使用架构。每个Account都有一个Order个对象的外来集合。每当您查询Account时,都会执行单独的查询以查找与特定Order对应的Account个对象的集合。这意味着每个Order必须有一个外部Account对象。

相关问题