【问题标题】:Create table with Foreign Collection Field使用外部集合字段创建表
【发布时间】:2012-04-23 20:13:43
【问题描述】:

我有这个抽象类:

域项

abstract public class DomainItem {

    @DatabaseField(generatedId = true)
    protected long id;

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

    //getters and setters
}

内容项:

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(){

    }

}

植物园内容

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

【问题讨论】:

    标签: java ormlite foreign-collection


    【解决方案1】:

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

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

    我感到困惑的原因是因为我没有找到任何示例代码(在文档或示例项目中),其中“包含的类”引用了带有集合的类。它是口头描述的,但考虑到关系的性质 - 对于某些描述,我认为在最初几次看到它时可能会有点难以理解。

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

    另外,还有一个说明需要将collection-holder类设置到collection元素类中。


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

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

    @ForeignCollectionField(eager = true)

    B.在集合(本例中为ContentItem中包含的类中,您必须有一个指向包含该集合的父类的显式引用:

    @DatabaseField(foreign = true) protected DomainItem domainItem;

    C.在持久化 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;
        }
    }
    

    【讨论】:

      【解决方案2】:

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

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

      看起来是这样。每当您拥有ForeignCollection 时,集合所包含的类必须具有返回父类的外部字段。

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

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

      【讨论】:

      • 有效!我拉出了抽象类的关系。现在它们在每个 'Item' 和各自的 'Content' 中。谢谢!!!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      相关资源
      最近更新 更多