[英]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 fieldcontentItens
column-name does not contain a foreign field of classPhytoterapicItem
字段
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. 外部集合文档中的
Account
和Order
对象示例可以帮助您使用模式。 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.