2012-04-23 8 views
11

Ich habe diese abstrakte Klasse:Erstellen Tabelle mit Fremd Sammlung Feld

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 
} 

Und diese (keine Zusammenfassung):

@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 meinem DatabaseHelper ich versucht, die Tabellen erstellen:

//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{ 
     ... 
    } 

Die Tabelle PhytoterapicContent erstellt wird. Aber ich habe den folgenden Fehler:

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

Antwort

11

Also die Ausnahme Nachricht wurde entwickelt, um hier zu helfen. Um es mit den entfernten Klassennamen zu zitieren:

Das sieht so aus. Immer wenn Sie ForeignCollection haben, muss die Klasse, die von der Auflistung enthalten ist, ein fremdes Feld zurück zu der übergeordneten Klasse haben.

In Ihrem Fall erweitert PhytoterapicItem die DomainItem Klasse, die eine ForeignCollection von ContentItem Objekte hat. Das bedeutet, dass ContentItem ein Fremdfeld vom Typ PhytoterapicItem haben muss. Wie sonst würde ORMLite wissen, welche der ContentItem Elemente in der Tabelle mit einer bestimmten PhytoterapicItem zugeordnet sind.

Das Beispiel Account und Order Objekte in der foreign collection documentation kann Ihnen bei Ihrem Schema helfen. Jede Account hat eine ausländische Sammlung von Order Objekte. Wenn Sie nach einem Account abfragen, wird eine separate Abfrage durchgeführt, um die Auflistung von Order Objekten zu finden, die einem bestimmten Account entsprechen. Das bedeutet, dass jede Order ein fremdes Account Objekt haben muss.

+0

Works! Ich habe die Beziehungen der abstrakten Klassen herausgezogen. Jetzt sind sie in jedem 'Item' und in jedem 'Content' enthalten. Danke!!! – Munir

11

Es dauerte eine Weile zu bemerken/verstehen diese kritische Block von den docs (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.

Der Grund, warum ich war verwirrt, weil ich kein Beispiel-Code (in docs oder Beispiel gefunden Projekte), in denen die "enthaltene Klasse" die Klasse mit der Sammlung referenziert. Es wird verbal beschrieben, aber angesichts der Art der Beziehung - für einige die Beschreibung, die ich denke, kann ein bisschen schwierig zu folgen, wenn es die ersten Male zu sehen.

Wie in der ursprünglichen Frage oben aufgeführten (das ist, wie ich die Idee, endlich die Lösung, die ich gestolpert, um zu versuchen) das Beispiel Block unter scheint der richtige Weg zu sein, um eine Eins-zu-zur Karte viele Sammelbeziehungen in OrmLite.

Darüber hinaus gibt es einen Hinweis darüber, wie die Collection-Holder-Klasse in die Collection-Elementklasse gesetzt werden muss.


Hier sind die wichtigsten Schritte zu kümmern:

A. In der Klasse, die die Sammlung (DomainItem in diesem Fall) hat, mit Anmerkungen versehen diese Weise Sammelgebiet:

B. In der Klasse, die in der Sammlung enthalten ist (ContentItem in diesem Fall) Sie einen ausdrücklichen Verweis zurück auf die Elternklasse haben müssen, die die Sammlung enthält:

@DatabaseField(foreign = true) protected DomainItem domainItem;

C. Vor persistierenden ContentItem, müssen Sie die DomainItem zu diesem ContentItem speichern, um sie einzustellen der Fremdschlüssel zu DomainItem zurück:

curContentItem.setDomainItem(curDomainItem); 

contentItemDao.create(curContentItem);` 

ich dachte, dies aus, wenn meine Sammlung zunächst nicht abgerufen wurde. Ich schaute auf die Tabelle für ContentItem, und die DomainItem_id wurde nie dort festgelegt.

Beispiel:

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