使用Foreign Collection Field创建表

我有这个抽象类:

DomainItem

abstract public class DomainItem { @DatabaseField(generatedId = true) protected long id; @ForeignCollectionField(eager = false) protected ForeignCollection 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的外部字段

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

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

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

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

外部集合文档中的AccountOrder对象示例可以帮助您使用模式。 每个Account都有一个Order对象的外部集合。 每当您查询Account都会执行单独的查询以查找与特定Account对应的Order对象的集合。 这意味着每个Order必须有一个外部Account对象。

从文档( 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);` 

当我最初没有检索到我的collections时,我想到了这一点。 我查看了ContentItem的表,并且从未在那里设置DomainItem_id。

例:

 public class DomainItem { @DatabaseField(generatedId = true) protected long id; @ForeignCollectionField(eager = false) protected ForeignCollection contentItens; // ... } public class ContentItem { @DatabaseField(generatedId = true) protected long id; @DatabaseField(foreign = true) protected DomainItem domainItem; public void setDomainItem(DomainItem domainItem) { this.domainItem = domainItem; } }