Search in sources :

Example 1 with ForeignCollectionField

use of com.j256.ormlite.field.ForeignCollectionField in project ormlite-android by j256.

the class DatabaseTableConfigUtil method configFromField.

/**
	 * Extract our configuration information from the field by looking for a {@link DatabaseField} annotation.
	 */
private static DatabaseFieldConfig configFromField(DatabaseType databaseType, String tableName, Field field) throws SQLException {
    if (configFieldNums == null) {
        return DatabaseFieldConfig.fromField(databaseType, tableName, field);
    }
    /*
		 * This, unfortunately, we can't get around. This creates a AnnotationFactory, an array of AnnotationMember
		 * fields, and possibly another array of AnnotationMember values. This creates a lot of GC'd objects.
		 */
    DatabaseField databaseField = field.getAnnotation(DatabaseField.class);
    DatabaseFieldConfig config = null;
    try {
        if (databaseField != null) {
            config = buildConfig(databaseField, tableName, field);
        }
    } catch (Exception e) {
    // ignored so we will configure normally below
    }
    if (config == null) {
        /*
			 * We configure this the old way because we might be using javax annotations, have a ForeignCollectionField,
			 * or may still be using the deprecated annotations. At this point we know that there isn't a @DatabaseField
			 * or we can't do our reflection hacks for some reason.
			 */
        return DatabaseFieldConfig.fromField(databaseType, tableName, field);
    } else {
        workedC++;
        return config;
    }
}
Also used : DatabaseField(com.j256.ormlite.field.DatabaseField) DatabaseFieldConfig(com.j256.ormlite.field.DatabaseFieldConfig) SQLException(java.sql.SQLException)

Example 2 with ForeignCollectionField

use of com.j256.ormlite.field.ForeignCollectionField in project robospice by stephanenicolas.

the class InDatabaseObjectPersister method saveAllForeignObjectsToCache.

/**
 * During this operation, we must save a new POJO (parent) into the database. The problem is
 * that is the POJO contains children POJOs, then saving the parent would not work as the parent
 * must exist in the database prior to saving the children. SO :
 * <ul>
 * <li>we copy the children into memory,
 * <li>put the children to null on parent
 * <li>save the parent to the database
 * <li>if saving filled the parent with previous children, we remove them
 * <li>re inject the children into the parent
 * <li>save the children (as the parent now exists in database).
 * </ul>
 *
 * @param data the parent POJO to save in the database.
 * @throws SQLException
 * @throws IllegalArgumentException
 * @throws IllegalAccessException
 * @throws InvocationTargetException
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
protected <E> void saveAllForeignObjectsToCache(E data) throws SQLException, IllegalAccessException, InvocationTargetException {
    // copy children on memory
    // set children to null on parents so that we can save the parent
    // without cascade
    Map<Field, Collection<?>> mapFieldToCollection = new HashMap<Field, Collection<?>>();
    Class<? extends Object> parentClass = data.getClass();
    for (Field field : parentClass.getDeclaredFields()) {
        ForeignCollectionField annotation = field.getAnnotation(ForeignCollectionField.class);
        if (annotation != null) {
            Collection<?> collectionCopy = new ArrayList();
            Method getMethod = DatabaseFieldConfig.findGetMethod(field, true);
            Collection collectionInObject = (Collection<?>) getMethod.invoke(data);
            if (collectionInObject != null) {
                collectionCopy.addAll(collectionInObject);
            }
            Method setMethod = DatabaseFieldConfig.findSetMethod(field, true);
            setMethod.invoke(data, (Object) null);
            mapFieldToCollection.put(field, collectionCopy);
        }
    }
    // save parents without cascade
    databaseHelper.createOrUpdateInDatabase(data, (Class<E>) parentClass);
    // get the child from a previous database record
    databaseHelper.refreshFromDatabase(data, (Class<E>) parentClass);
    // collection field of the parent
    for (Field field : parentClass.getDeclaredFields()) {
        if (field.getAnnotation(ForeignCollectionField.class) != null) {
            Method getMethod = DatabaseFieldConfig.findGetMethod(field, true);
            Collection collectionInObject = (Collection<?>) getMethod.invoke(data);
            // lazy collection are not loaded from database, so we load them
            if (collectionInObject instanceof LazyForeignCollection) {
                ((LazyForeignCollection) collectionInObject).refreshCollection();
            }
            ParameterizedType listType = (ParameterizedType) field.getGenericType();
            Class<?> itemInListClass = (Class<?>) listType.getActualTypeArguments()[0];
            databaseHelper.deleteFromDataBase(collectionInObject, itemInListClass);
        }
    }
    // we now saved the parent and can fill the foreign key of the children
    for (Map.Entry<Field, Collection<?>> entry : mapFieldToCollection.entrySet()) {
        Collection<?> collection = entry.getValue();
        // re-set complete children to the parent
        ConnectionSource connectionSource = databaseHelper.getConnectionSource();
        for (Object object : collection) {
            DatabaseTableConfig childDatabaseTableConfig = DatabaseTableConfig.fromClass(connectionSource, object.getClass());
            for (FieldType childFieldType : childDatabaseTableConfig.getFieldTypes(null)) {
                if (parentClass.equals(childFieldType.getType()) && childFieldType.isForeign()) {
                    childFieldType.assignField(object, data, true, null);
                }
            }
            // save children recursively
            saveAllForeignObjectsToCache(object);
        }
    }
    // notify
    if (mapHandledClassesToNotificationUri != null && mapHandledClassesToNotificationUri.containsKey(parentClass)) {
        Uri notificationUri = mapHandledClassesToNotificationUri.get(parentClass);
        if (notificationUri != null) {
            getApplication().getContentResolver().notifyChange(notificationUri, null);
            Object id = getIdField(data.getClass()).extractJavaFieldValue(data);
            Uri itemNotificationUri = notificationUri.buildUpon().appendPath(id.toString()).build();
            getApplication().getContentResolver().notifyChange(itemNotificationUri, null);
        }
    }
// future hook
}
Also used : ForeignCollectionField(com.j256.ormlite.field.ForeignCollectionField) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) Uri(android.net.Uri) FieldType(com.j256.ormlite.field.FieldType) ParameterizedType(java.lang.reflect.ParameterizedType) ForeignCollectionField(com.j256.ormlite.field.ForeignCollectionField) Field(java.lang.reflect.Field) LazyForeignCollection(com.j256.ormlite.dao.LazyForeignCollection) ConnectionSource(com.j256.ormlite.support.ConnectionSource) Collection(java.util.Collection) LazyForeignCollection(com.j256.ormlite.dao.LazyForeignCollection) HashMap(java.util.HashMap) Map(java.util.Map) DatabaseTableConfig(com.j256.ormlite.table.DatabaseTableConfig)

Example 3 with ForeignCollectionField

use of com.j256.ormlite.field.ForeignCollectionField in project robospice by stephanenicolas.

the class RoboSpiceDatabaseHelper method clearTable.

private <T> void clearTable(Class<T> clazz) throws SQLException {
    for (Field field : clazz.getDeclaredFields()) {
        ForeignCollectionField annotation = field.getAnnotation(ForeignCollectionField.class);
        if (annotation != null) {
            ParameterizedType stringListType = (ParameterizedType) field.getGenericType();
            Class<?> itemInListClass = (Class<?>) stringListType.getActualTypeArguments()[0];
            clearTable(itemInListClass);
        }
    }
    TableUtils.dropTable(getConnectionSource(), clazz, true);
    TableUtils.createTableIfNotExists(getConnectionSource(), clazz);
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) Field(java.lang.reflect.Field) ForeignCollectionField(com.j256.ormlite.field.ForeignCollectionField) ForeignCollectionField(com.j256.ormlite.field.ForeignCollectionField)

Aggregations

ForeignCollectionField (com.j256.ormlite.field.ForeignCollectionField)2 Field (java.lang.reflect.Field)2 ParameterizedType (java.lang.reflect.ParameterizedType)2 Uri (android.net.Uri)1 LazyForeignCollection (com.j256.ormlite.dao.LazyForeignCollection)1 DatabaseField (com.j256.ormlite.field.DatabaseField)1 DatabaseFieldConfig (com.j256.ormlite.field.DatabaseFieldConfig)1 FieldType (com.j256.ormlite.field.FieldType)1 ConnectionSource (com.j256.ormlite.support.ConnectionSource)1 DatabaseTableConfig (com.j256.ormlite.table.DatabaseTableConfig)1 Method (java.lang.reflect.Method)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1