java 创建带有外部集合字段的表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10287578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:23:23  来源:igfitidea点击:

Create table with Foreign Collection Field

javaormliteforeign-collection

提问by Munir

I have this abstract class:

我有这个抽象类:

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
}

And these (no abstract):

而这些(没有摘要):

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

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. But I got the follow error:

表 PhytoterapicContent 已创建。但我收到以下错误:

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

采纳答案by Gray

So the exception message was designed to help here. To quote it with the class names removed:

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

Foreign collection class ContentItemfor field contentItenscolumn-name does not contain a foreign field of class PhytoterapicItem

ContentItem字段contentItens列名的外部集合类不包含类的外部字段PhytoterapicItem

That looks to be the case. Whenever you have ForeignCollection, the class contained by the collection musthave a foreign field back to the parent class.

看起来是这样。无论何时ForeignCollection,集合所包含的类都必须有一个返回父类的外部字段。

In your case, PhytoterapicItemextends the DomainItemclass which has a ForeignCollectionof ContentItemobjects. That means that ContentItemmust have a foreign field of type PhytoterapicItem. Otherwise, how would ORMLiteknow which of the ContentItemitems in the table are associated with a particular PhytoterapicItem.

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

The example of Accountand Orderobjects in the foreign collection documentationmay help you with your schema. Each Accounthas a foreign collection of Orderobjects. Whenever you query for an Accounta separate query is performed to find the collection of Orderobjects that correspond to a particular Account. That means that each Orderhas to have a foreign Accountobject.

外部集合文档中AccountOrder对象示例可能会帮助您了解架构。每个都有一个外部对象集合。每当您查询一个单独的查询时,都会执行以查找与特定. 这意味着每个人都必须有一个异物。AccountOrderAccountOrderAccountOrderAccount

回答by Gene Bo

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). If Account has a foreign collection of Orders, then Order must have an Account foreign field. It is required so ORMLite can find the orders that match a particular account.

请记住,当您有一个 ForeignCollection 字段时,集合中的类(在此示例中为 Order)必须具有包含该集合的类(在此示例中为 Account)的外部字段。如果 Account 有一个外部的 Orders 集合,那么 Order 必须有一个 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 wayto 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.

另外,collection-holder类需要如何设置到collection元素类中,还有一个注意事项。



Here are the main steps to take care of:

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

A. In the class that has the collection (DomainItemin this case), annotate collection field this way:

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

@ForeignCollectionField(eager = true)

@ForeignCollectionField(eager = true)

B. In the class that is contained in the collection (ContentItemin 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;

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