studio simple micro fortnite ejemplo android ormlite

android - simple - ormlite c#



Guardar objetos extraños anidados con ORMLite en Android (4)

Al hacer esto, el objeto padre se conserva pero no el objeto secundario y la columna auto_id_child_id en la tabla primaria se establece en 0. ¿Es este comportamiento normal?

OrmLite no guarda automáticamente objetos anidados automágicamente como otros ORM. Está diseñado tomando en serio la parte "Lite" de su nombre y con el lema de KISS en mente.

Sin embargo, puede hacer que los objetos anidados funcionen fácilmente creando el elemento secundario antes de crear el elemento primario.

Parent parent = new Parent(); parent.name = "ParentName"; Child child = new Child(); child.name = "ChildName"; parent.child = child; // this will update the id in child childDao.create(child); // this saves the parent with the id of the child parentDao.create(parent);

Una cosa más a tener en cuenta es que cuando consulta un objeto Parent, el objeto secundario que obtiene solo recupera su campo id. Si el ID es un int generado automáticamente (por ejemplo), el campo de nombre anterior no se recuperará hasta que realice una actualización en el objeto secundario.

// assuming the id of the Parent is the name Parent parent = parentDao.queryForId("ParentName"); System.out.println("Child id should be set: " + parent.child.id); System.out.println("Child name should be null: " + parent.child.name); // now we refresh the child object to load all of the fields childDao.refresh(parent.child); System.out.println("Child name should now be set: " + parent.child.name);

Para obtener más documentación sobre esto, consulte la página en línea sobre Campos de objetos extraños .

Al trabajar en Android, ¿ORMLite solo guarda objetos de nivel superficial? Tengo una estructura de datos con Objetos anidados, ambos recién creados, y me gustaría poder guardarlos con una sola llamada a dao.create ()

Por ejemplo, tengo la siguiente clase para padres.

@DatabaseTable public class Parent { @DatabaseField(generatedId=true) public int id; @DatabaseField public String name; @DatabaseField public Child child; }

y la siguiente clase de niños.

@DatabaseTable public class Child { @DatabaseField(generatedId=true) public int id; @DatabaseField public String name; }

Quiero ser capaz de hacer lo siguiente.

Parent parent = new Parent(); parent.name = "ParentName"; Child child = new Child(); child.name = "ChildName"; parent.child = child; // .. get helper and create dao object... dao.create(parent);

Al hacer esto, el objeto padre se conserva pero no el objeto secundario y la columna child_id en la tabla primaria se establece en 0. ¿Es este comportamiento normal? ¿Hay alguna manera de mantener persistentes los objetos anidados y propagar la clave primaria?


¿Has intentado esto?

@DatabaseField(foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true) public Child child;

Estoy usando ORMLite 4.35.


Como se mencionó, esto no parece ser compatible con la versión lite. Escribí una función recursiva simple para guardar todos los objetos referenciados. Tuve problemas para que los genéricos funcionaran bien, así que al final simplemente los eliminé. También hice una clase base de Entidad para mis objetos db.

Así que aquí está lo que escribí. Si alguien puede obtener el mismo código para trabajar con genéricos adecuados, o puede mejorarlo, no dude en editarlo.

// Debugging identity tag public static final String TAG = DatabaseHelper.class.getName(); // Static map of common DAO objects @SuppressWarnings("rawtypes") private static final Map<Class, Dao<?, Integer>> sDaoClassMap = new HashMap<Class, Dao<?,Integer>>(); /** * Persist an entity to the underlying database. * * @param context * @param entity * @return boolean flag indicating success */ public static boolean create(Context context, Entity entity) { // Get our database manager DatabaseHelper databaseHelper = DatabaseHelper.getHelper(context); try { // Recursively save entity create(databaseHelper, entity); } catch (IllegalArgumentException e) { Log.e(TAG, "Object is not an instance of the declaring class", e); return false; } catch (IllegalAccessException e) { Log.e(TAG, "Field is not accessible from the current context", e); return false; } catch (SQLException e) { Log.e(TAG, "Unable to create object", e); return false; } // Release database helper DatabaseHelper.release(); // Return true on success return true; } /** * Persist an entity to the underlying database.<br><br> * For each field that has a DatabaseField annotation with foreign set to true, * and is an instance of Entity, recursive attempt to persist that entity as well. * * @param databaseHelper * @param entity * @throws IllegalArgumentException * @throws IllegalAccessException * @throws SQLException */ @SuppressWarnings("unchecked") public static void create(DatabaseHelper databaseHelper, Entity entity) throws IllegalArgumentException, IllegalAccessException, SQLException { // Class type of entity used for reflection @SuppressWarnings("rawtypes") Class clazz = entity.getClass(); // Search declared fields and save child entities before saving parent. for(Field field : clazz.getDeclaredFields()) { // Inspect annotations for(Annotation annotation : field.getDeclaredAnnotations()) { // Only consider fields with the DatabaseField annotation if(annotation instanceof DatabaseField) { // Check for foreign attribute DatabaseField databaseField = (DatabaseField)annotation; if(databaseField.foreign()) { // Check for instance of Entity Object object = field.get(entity); if(object instanceof Entity) { // Recursive persist referenced entity create(databaseHelper, (Entity)object); } } } } } // Retrieve the common DAO for the entity class Dao<Entity, Integer> dao = (Dao<Entity, Integer>) sDaoClassMap.get(clazz); // If the DAO does not exist, create it and add it to the static map if(dao == null) { dao = BaseDaoImpl.createDao(databaseHelper.getConnectionSource(), clazz); sDaoClassMap.put(clazz, dao); } // Persist the entity to the database dao.create(entity); }


@DatabaseField(foreign = true,foreignAutoCreate = true,foreignAutoRefresh = true) public Child child;

Algunas notas sobre esta solución

  1. (foreignAutoCreate = true) funciona solo si el campo ID no está configurado (nulo o 0) según la documentación de ORMlite http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/field/DatabaseField.html

    • foreignAutoCreate: "Configure esto para que sea verdadero (valor predeterminado falso) para que el campo foráneo se cree automágicamente usando su DAO interno si el campo ID no está establecido (nulo o 0)".
  2. Esto solo funciona si generateId también se establece en true para la tabla secundaria según la documentación de ORMlite .