All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.j256.ormlite.stmt.mapped.BaseMappedQuery Maven / Gradle / Ivy

Go to download

Lightweight Object Relational Model (ORM) for persisting objects to SQL databases.

There is a newer version: 6.1
Show newest version
package com.j256.ormlite.stmt.mapped;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import com.j256.ormlite.dao.BaseForeignCollection;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.ObjectCache;
import com.j256.ormlite.field.FieldType;
import com.j256.ormlite.stmt.GenericRowMapper;
import com.j256.ormlite.support.DatabaseResults;
import com.j256.ormlite.table.TableInfo;

/**
 * Abstract mapped statement for queries which handle the creating of a new object and the row mapping functionality.
 * 
 * @author graywatson
 */
public abstract class BaseMappedQuery extends BaseMappedStatement implements GenericRowMapper {

	protected final FieldType[] resultsFieldTypes;
	// cache of column names to results position
	private Map columnPositions = null;
	private Object parent = null;
	private Object parentId = null;

	protected BaseMappedQuery(Dao dao, TableInfo tableInfo, String statement, FieldType[] argFieldTypes,
			FieldType[] resultsFieldTypes) {
		super(dao, tableInfo, statement, argFieldTypes);
		this.resultsFieldTypes = resultsFieldTypes;
	}

	@Override
	public T mapRow(DatabaseResults results) throws SQLException {
		Map colPosMap;
		if (columnPositions == null) {
			colPosMap = new HashMap();
		} else {
			colPosMap = columnPositions;
		}

		ObjectCache objectCache = results.getObjectCacheForRetrieve();
		if (objectCache != null) {
			Object id = idField.resultToJava(results, colPosMap);
			T cachedInstance = objectCache.get(clazz, id);
			if (cachedInstance != null) {
				// if we have a cached instance for this id then return it
				return cachedInstance;
			}
		}

		// create our instance
		T instance = dao.createObjectInstance();
		// populate its fields
		Object id = null;
		boolean foreignCollections = false;
		for (FieldType fieldType : resultsFieldTypes) {
			if (fieldType.isForeignCollection()) {
				foreignCollections = true;
			} else {
				Object val = fieldType.resultToJava(results, colPosMap);
				/*
				 * This is pretty subtle. We introduced multiple foreign fields to the same type which use the {@link
				 * ForeignCollectionField} foreignColumnName field. The bug that was created was that all the fields
				 * were then set with the parent class. Only the fields that have a matching id value should be set to
				 * the parent. We had to add the val.equals logic.
				 */
				if (val != null && parent != null && fieldType.getField().getType() == parent.getClass()
						&& val.equals(parentId)) {
					fieldType.assignField(connectionSource, instance, parent, true, objectCache);
				} else {
					fieldType.assignField(connectionSource, instance, val, false, objectCache);
				}
				if (fieldType.isId()) {
					id = val;
				}
			}
		}
		if (foreignCollections) {
			// go back and initialize any foreign collections
			for (FieldType fieldType : resultsFieldTypes) {
				if (fieldType.isForeignCollection()) {
					BaseForeignCollection collection = fieldType.buildForeignCollection(instance, id);
					if (collection != null) {
						fieldType.assignField(connectionSource, instance, collection, false, objectCache);
					}
				}
			}
		}
		// if we have a cache and we have an id then add it to the cache
		objectCache = results.getObjectCacheForStore();
		if (objectCache != null && id != null) {
			objectCache.put(clazz, id, instance);
		}
		if (columnPositions == null) {
			columnPositions = colPosMap;
		}
		return instance;
	}

	/**
	 * If we have a foreign collection object then this sets the value on the foreign object in the class.
	 */
	public void setParentInformation(Object parent, Object parentId) {
		this.parent = parent;
		this.parentId = parentId;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy