简体   繁体   English

使用Foreign Collection Field创建表

[英]Create table with Foreign Collection Field

I have this abstract class: 我有这个抽象类:

DomainItem DomainItem

abstract public class DomainItem {

    @DatabaseField(generatedId = true)
    protected long id;

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

    //getters and setters
}

ContentItem: ContentItem:

abstract public class ContentItem {

    @DatabaseField(generatedId = true)
    protected long id;

    @DatabaseField(foreign = true)
    protected DomainItem domainItem;


    @DatabaseField()
    protected String content;

    //getters and setters
}

And these (no abstract): 这些(没有摘要):

@DatabaseTable()
public class PhytoterapicItem extends DomainItem{

    public PhytoterapicItem(){

    }

}

PhytoterapicContent PhytoterapicContent

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

    @DatabaseField(canBeNull = false)
    private String defaultName;

    @DatabaseField(canBeNull = false)
    private String scientificName;

    //getters and setters
}

In my DatabaseHelper I trying create the tables: 在我的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{
       ...
    }

The table PhytoterapicContent is created. 表PhytoterapicContent已创建。 But I got the follow error: 但我得到了以下错误:

java.sql.SQLException: Foreign collection class br.com.project.model.ContentItem for field 'contentItens' column-name does not contain a foreign field of class br.com.project.model.PhytoterapicItem java.sql.SQLException:字段'contentItens'column-name的外部集合类br.com.project.model.ContentItem不包含类br.com.project.model.PhytoterapicItem的外部字段

It took me a while to notice/understand this critical block from the docs ( http://ormlite.com/docs/foreign-collection ): 我花了一段时间才注意到/从文档( http://ormlite.com/docs/foreign-collection )中了解这个关键块:

Remember that when you have a ForeignCollection field, the class in the collection must (in this example Order) must have a foreign field for the class that has the collection (in this example Account). 请记住,当您有一个ForeignCollection字段时,集合中的类必须(在此示例中为Order)必须具有包含该集合的类的外部字段(在此示例中为Account)。 If Account has a foreign collection of Orders, then Order must have an Account foreign field. 如果Account有一个外国的Orders集合,那么Order必须有一个Account外部字段。 It is required so ORMLite can find the orders that match a particular account. 这是必需的,因此ORMLite可以找到与特定帐户匹配的订单。

The reason I was confused is because I didn't find any example code (in docs or example projects) where the "contained class" references the class with the collection. 我之所以感到困惑的原因是因为我没有找到任何示例代码(在文档或示例项目中),其中“包含的类”引用带有集合的类。 It is described verbally, but given the nature of the relationship - for some the description I think can be a bit tricky to follow when seeing it the first few times. 它是口头描述的,但考虑到关系的性质 - 对于某些描述,我认为在前几次看到它时可能会有些棘手。

As listed above in the original question (which is how I finally got the idea to try the solution I stumbled upon) , the example block below seems to be the correct way to map a one-to-many collection relationship in OrmLite. 正如上面原始问题中所列出的那样(这是我最终想到尝试我偶然发现的解决方案的想法) ,下面的示例块似乎是在OrmLite中映射一对多集合关系的正确方法

In addition, there is a note about how the collection-holder class needs to be set into the collection element class. 此外,还有一个关于如何将集合持有者类设置到集合元素类中的说明。


Here are the main steps to take care of: 以下是需要注意的主要步骤:

A. In the class that has the collection ( DomainItem in this case) , annotate collection field this way: A.在具有集合的类(本例中为DomainItem )中 ,以这种方式注释集合字段:

@ForeignCollectionField(eager = true)

B. In the class that is contained in the collection ( ContentItem in this case) , you must have an explicit reference back to the parent class that contains the collection: B.在集合中包含的类(本例中为ContentItem )中 ,您必须具有对包含集合的父类的显式引用:

@DatabaseField(foreign = true) protected DomainItem domainItem;

C. Before persisting ContentItem, you must save the DomainItem to that ContentItem in order to set the foreign key back to DomainItem: C.在持久化ContentItem之前,必须将DomainItem保存到该ContentItem,以便将外键设置回DomainItem:

curContentItem.setDomainItem(curDomainItem);

contentItemDao.create(curContentItem);`

I figured this out when my collection wasn't being retrieved initially. 当我最初没有检索到我的收藏时,我想到了这一点。 I looked at the table for ContentItem, and the DomainItem_id was never set there. 我查看了ContentItem的表,并且从未在那里设置DomainItem_id。

EXAMPLE: 例:

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

So the exception message was designed to help here. 所以异常消息旨在帮助这里。 To quote it with the class names removed: 引用删除的类名称引用它:

Foreign collection class ContentItem for field contentItens column-name does not contain a foreign field of class PhytoterapicItem 字段contentItens column-name的外部集合类ContentItem不包含PhytoterapicItem类的外部字段

That looks to be the case. 看起来就是这样。 Whenever you have ForeignCollection , the class contained by the collection must have a foreign field back to the parent class. 每当你有ForeignCollection ,集合包含的类必须有一个返回父类的外部字段。

In your case, PhytoterapicItem extends the DomainItem class which has a ForeignCollection of ContentItem objects. 在您的情况下, PhytoterapicItem扩展DomainItem类,该类具有ContentItem对象的ForeignCollection That means that ContentItem must have a foreign field of type PhytoterapicItem . 这意味着ContentItem必须具有PhytoterapicItem类型的外部字段。 Otherwise, how would ORMLite know which of the ContentItem items in the table are associated with a particular PhytoterapicItem . 否则, ORMLite如何知道表中的哪个ContentItem项与特定的PhytoterapicItem相关联。

The example of Account and Order objects in the foreign collection documentation may help you with your schema. 外部集合文档中AccountOrder对象示例可以帮助您使用模式。 Each Account has a foreign collection of Order objects. 每个Account都有一个Order对象的外部集合。 Whenever you query for an Account a separate query is performed to find the collection of Order objects that correspond to a particular Account . 每当您查询Account都会执行单独的查询以查找与特定Account对应的Order对象的集合。 That means that each Order has to have a foreign Account object. 这意味着每个Order必须有一个外部Account对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM