2012-04-23 11 views
11

tengo esta clase abstracta:Crear una tabla con la colección de Asuntos Exteriores campo

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 
} 

Y éstos (sin resumen):

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

En mi DatabaseHelper que tratar de crear las tablas: se crea

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

El PhytoterapicContent mesa. Pero tengo el siguiente 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

Respuesta

11

Así que el mensaje de excepción fue diseñado para ayudar aquí. Para citar con los nombres de las clases eliminadas:

Foreign collection class ContentItem for field contentItens column-name does not contain a foreign field of class PhytoterapicItem

Ese parece ser el caso. Siempre que tenga ForeignCollection, la clase contenida en la colección debe tener un campo foráneo de regreso a la clase principal.

En su caso, PhytoterapicItem extiende la clase DomainItem que tiene una ForeignCollection de ContentItem objetos. Esto significa que ContentItem debe tener un campo foráneo del tipo PhytoterapicItem. De lo contrario, ¿cómo sabría ORMLite cuáles de los artículos ContentItem en la tabla están asociados con un particular PhytoterapicItem.

El ejemplo de los objetos Account y Order en el foreign collection documentation puede ayudarlo con su esquema. Cada Account tiene una colección extranjera de objetos Order. Cada vez que consulta un Account se realiza una consulta por separado para buscar la colección de objetos Order que corresponden a un particular Account. Eso significa que cada Order tiene que tener un objeto Account foráneo.

+0

Works! Saqué las relaciones de las clases abstractas. Ahora están en cada 'Artículo' y respectivo 'Contenido'. ¡¡¡Gracias!!! – Munir

11

Me tomó un tiempo para notar/entender este bloque crítico de los documentos (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.

La razón por la que estaba confundido es porque no he encontrado ningún código de ejemplo (en el ejemplo Docs o proyectos) donde la "clase contenida" hace referencia a la clase con la colección. Se describe verbalmente, pero dada la naturaleza de la relación, para algunos la descripción creo que puede ser un poco difícil de seguir al verla las primeras veces.

como se indica anteriormente en la pregunta original (que es lo que finalmente me dio la idea para tratar la solución me topé), el bloque siguiente ejemplo parece ser la forma correcta para asignar un uno-a mucha relación de colección en OrmLite.

Además, hay una nota sobre cómo la clase poseedor de la colección necesita establecerse en la clase de elemento de colección.


Éstos son los pasos principales para hacerse cargo de:

A. En la clase que tiene la colección (DomainItem en este caso), anotar campo de recolección de esta manera:

@ForeignCollectionField(eager = true)

B. en la clase que está contenido en la colección (ContentItem en este caso), debe tener una referencia explícita a la clase principal que contiene la colección:

@DatabaseField(foreign = true) protected DomainItem domainItem;

C. Antes de que persiste ContentItem, debe guardar el DomainItem a que ContentItem con el fin de establecer la clave externa de nuevo a DomainItem:

curContentItem.setDomainItem(curDomainItem); 

contentItemDao.create(curContentItem);` 

me cuenta de esto cuando mi colección no se está recuperando inicialmente. Miré la tabla para ContentItem, y DomainItem_id nunca se estableció allí.

Ejemplo:

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; 
    } 
} 
Cuestiones relacionadas