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

com.jpattern.orm.session.OrmSession Maven / Gradle / Ivy

There is a newer version: 6.3.0
Show newest version
package com.jpattern.orm.session;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jpattern.orm.exception.OrmException;
import com.jpattern.orm.exception.OrmNotUniqueResultException;
import com.jpattern.orm.exception.OrmOptimisticLockException;
import com.jpattern.orm.mapper.IOrmClassTool;
import com.jpattern.orm.mapper.IOrmClassToolMap;
import com.jpattern.orm.persistor.IOrmPersistor;
import com.jpattern.orm.persistor.type.TypeFactory;
import com.jpattern.orm.persistor.type.ext.WrapperTypeArray;
import com.jpattern.orm.query.OrmClassToolMapNameSolver;
import com.jpattern.orm.query.delete.DeleteQuery;
import com.jpattern.orm.query.delete.DeleteQueryOrm;
import com.jpattern.orm.query.find.CustomFindQuery;
import com.jpattern.orm.query.find.FindQuery;
import com.jpattern.orm.query.find.CustomFindQueryOrm;
import com.jpattern.orm.query.find.FindQueryOrm;
import com.jpattern.orm.query.sql.PlainSqlExecutor;
import com.jpattern.orm.query.sql.SqlExecutor;
import com.jpattern.orm.query.update.UpdateQueryOrm;
import com.jpattern.orm.query.update.UpdateQuery;
import com.jpattern.orm.script.ScriptExecutor;
import com.jpattern.orm.script.ScriptExecutorImpl;
import com.jpattern.orm.transaction.Transaction;
import com.jpattern.orm.transaction.TransactionDefinition;
import com.jpattern.orm.transaction.OrmTransactionDefinition;
import com.jpattern.orm.validator.Validator;

/**
 * 
 * @author Francesco Cina
 *
 * 27/giu/2011
 */
public class OrmSession implements SessionSqlPerformer {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	private final IOrmClassToolMap ormClassToolMap;
	private final SessionStrategy sessionStrategy;
	private final WrapperTypeArray wrapperTypeArray;
	private final Validator validator;
	private final TypeFactory typeFactory;

	public OrmSession(final IOrmClassToolMap ormClassToolMap, final SessionStrategy sessionStrategy, final TypeFactory typeFactory, final Validator validator) {
		this.ormClassToolMap = ormClassToolMap;
		this.sessionStrategy = sessionStrategy;
		this.typeFactory = typeFactory;
		this.validator = validator;
		this.wrapperTypeArray = new WrapperTypeArray(typeFactory);
	}

	@Override
	public final Transaction transaction() throws OrmException {
		return this.transaction(new OrmTransactionDefinition());
	}

	@Override
	public final  FindQuery findQuery(final Class clazz) throws OrmException {
		final OrmClassToolMapNameSolver nameSolver = new OrmClassToolMapNameSolver(this.ormClassToolMap);
		final FindQueryOrm query = new FindQueryOrm(this.ormClassToolMap , this, clazz, nameSolver.register(clazz), this.typeFactory );
		query.setNameSolver(nameSolver);
		return query;
	}

	@Override
	public final  FindQuery findQuery(final Class clazz, final String alias) throws OrmException {
		final OrmClassToolMapNameSolver nameSolver = new OrmClassToolMapNameSolver(this.ormClassToolMap);
		final FindQueryOrm query = new FindQueryOrm(this.ormClassToolMap , this, clazz, nameSolver.register(clazz, alias), this.typeFactory);
		query.setNameSolver(nameSolver);
		return query;
	}

	@Override
	public final CustomFindQuery findQuery(final String selectClause, final Class clazz, final String alias ) throws OrmException {
		final OrmClassToolMapNameSolver nameSolver = new OrmClassToolMapNameSolver(this.ormClassToolMap);
		final CustomFindQueryOrm query = new CustomFindQueryOrm(selectClause, this.ormClassToolMap , this, clazz, nameSolver.register(clazz, alias), this.typeFactory);
		query.setNameSolver(nameSolver);
		return query;
	}

	public final IOrmClassToolMap getOrmClassToolMap() {
		return this.ormClassToolMap;
	}

	@Override
	public final  T find(final Class clazz, final Object value) throws OrmException {
		return this.find(clazz, new Object[]{value});
	}

	@Override
	public final  T find(final Class clazz, final Object[] values) throws OrmException {
		final IOrmClassTool ormClassTool = getOrmClassToolMap().getOrmClassTool(clazz);
		final ResultSetReader resultSetReader = new ResultSetReader() {

			@Override
			public T read(final ResultSet resultSet) throws SQLException {
				if ( resultSet.next() ) {
					final T result = ormClassTool.getOrmPersistor().mapRow("", resultSet, 0);
					if (resultSet.next()) {
						throw new OrmNotUniqueResultException("The query execution returned more than one object. Zero or one expected.");
					}
					return result;
				}
				return null;
			}
		};
		final SqlPerformer sqlExec = sqlPerformer();
		sqlExec.setMaxRows(1);
		return sqlExec.query(ormClassTool.getOrmCRUDQuery().getLoadQuery(), resultSetReader, this.wrapperTypeArray.unWrap(values));
	}

	@Override
	public final  T findUnique(final Class clazz, final Object value) throws OrmException, OrmNotUniqueResultException {
		return this.findUnique(clazz, new Object[]{value});
	}

	@Override
	public final  T findUnique(final Class clazz, final Object[] values) throws OrmException, OrmNotUniqueResultException {
		final T result = this.find(clazz, values);
		if (result==null) {
			throw new OrmNotUniqueResultException("No objects found.");
		}
		return result;
	}

	@Override
	public final  T save(final T object) throws OrmException {
		this.validator.validate(object);
		@SuppressWarnings("unchecked")
		final IOrmClassTool ormClassTool = (IOrmClassTool) getOrmClassToolMap().getOrmClassTool(object.getClass());
		final IOrmPersistor persistor = ormClassTool.getOrmPersistor();
		final SqlPerformer sqlExec = sqlPerformer();
		final T resultObject = ormClassTool.getOrmPersistor().clone(object);
		//		final String sql = ormClassTool.getOrmCRUDQuery().getSaveQuery();

		//CHECK IF OBJECT HAS A 'VERSION' FIELD and increase it
		persistor.increaseVersion(resultObject, true);


		if (!ormClassTool.getOrmPersistor().useKeyGenerators(resultObject)) {
			if (this.logger.isDebugEnabled()) {
				this.logger.debug("Saving object without using generators");
			}
			final String sql = ormClassTool.getOrmCRUDQuery().getSaveQueryWithoutGenerators();
			sqlExec.update(sql, new PreparedStatementSetter() {
				@Override
				public void set(final PreparedStatement ps) throws SQLException {
					persistor.setAllValues(resultObject, ps);
				}});
		} else {
			if (this.logger.isDebugEnabled()) {
				this.logger.debug("Saving object using generators");
			}
			final String sql = ormClassTool.getOrmCRUDQuery().getSaveQuery();
			final GeneratedKeyReader generatedKeyExtractor = new GeneratedKeyReader() {

				@Override
				public void read(final ResultSet generatedKeyResultSet) throws SQLException {
					if (generatedKeyResultSet.next()) {
						ormClassTool.getOrmPersistor().updateGeneratedValues(generatedKeyResultSet, resultObject);
					}
				}

				@Override
				public String[] generatedColumnNames() {
					return ormClassTool.getClassMap().getAllGeneratedColumnDBNames();
				}
			};
			sqlExec.update(sql, generatedKeyExtractor, new PreparedStatementSetter() {

				@Override
				public void set(final PreparedStatement ps) throws SQLException {
					persistor.setAllNotGeneratedValues(resultObject, ps);
				}});
		}
		return resultObject;
	}

	@Override
	public final  T update(final T object) throws OrmException {
		this.validator.validate(object);
		@SuppressWarnings("unchecked")
		final
		IOrmClassTool ormClassTool = (IOrmClassTool) getOrmClassToolMap().getOrmClassTool(object.getClass());
		final IOrmPersistor persistor = ormClassTool.getOrmPersistor();
		final SqlPerformer sqlExec = sqlPerformer();
		final T resultObject = persistor.clone(object);

		//CHECK IF OBJECT HAS A 'VERSION' FIELD
		if (ormClassTool.getOrmPersistor().isVersionable()) {
			final int rightVersion = sqlExec.queryForInt(ormClassTool.getOrmCRUDQuery().getBeanVersionQuery(), ormClassTool.getOrmPersistor().primaryKeyAndVersionValues(resultObject));
			if ( rightVersion==0 ) {
				throw new OrmOptimisticLockException("The bean of class [" + resultObject.getClass() + "] cannot be updated. Version in the DB is not the expected one.");
			}
			ormClassTool.getOrmPersistor().increaseVersion(resultObject, false);
		}

		//UPDATE OBJECT
		PreparedStatementSetter pss = new PreparedStatementSetter() {

			@Override
			public void set(final PreparedStatement ps) throws SQLException {
				persistor.setNotPrimaryKeyAndThenPrimaryKeyValues(resultObject, ps);
			}
		};
		sqlExec.update(ormClassTool.getOrmCRUDQuery().getUpdateQuery(), pss);
		return resultObject;
	}


	@Override
	public final UpdateQuery updateQuery(final Class clazz) throws OrmException {
		final OrmClassToolMapNameSolver nameSolver = new OrmClassToolMapNameSolver(this.ormClassToolMap);
		nameSolver.alwaysResolveWithoutAlias(true);
		nameSolver.register(clazz);
		final UpdateQueryOrm update = new UpdateQueryOrm(clazz, this.ormClassToolMap, this, this.typeFactory);
		update.setNameSolver(nameSolver);
		return update;
	}

	@Override
	public final UpdateQuery updateQuery(final Class clazz, final String alias) throws OrmException {
		final OrmClassToolMapNameSolver nameSolver = new OrmClassToolMapNameSolver(this.ormClassToolMap);
		nameSolver.alwaysResolveWithoutAlias(true);
		nameSolver.register(clazz, alias);
		final UpdateQueryOrm update = new UpdateQueryOrm(clazz, this.ormClassToolMap, this, this.typeFactory);
		update.setNameSolver(nameSolver);
		return update;
	}

	@Override
	public final  int delete(final T object) throws OrmException {
		@SuppressWarnings("unchecked")
		final
		IOrmClassTool ormClassTool = (IOrmClassTool) getOrmClassToolMap().getOrmClassTool(object.getClass());
		final SqlPerformer sqlExec = sqlPerformer();
		return sqlExec.update(ormClassTool.getOrmCRUDQuery().getDeleteQuery(), ormClassTool.getOrmPersistor().primaryKeyValues(object));
	}

	@Override
	public final  int delete(final List objects) throws OrmException {
		int result = 0;
		for (final T object : objects) {
			result += this.delete(object);
		}
		return result;
	}

	@Override
	public final DeleteQuery deleteQuery(final Class clazz) throws OrmException {
		final OrmClassToolMapNameSolver nameSolver = new OrmClassToolMapNameSolver(this.ormClassToolMap);
		nameSolver.register(clazz);
		nameSolver.alwaysResolveWithoutAlias(true);
		final DeleteQueryOrm delete = new DeleteQueryOrm(clazz, this.ormClassToolMap, this, this.typeFactory);
		delete.setNameSolver(nameSolver);
		return delete;
	}

	@Override
	public final DeleteQuery deleteQuery(final Class clazz, final String alias) throws OrmException {
		final OrmClassToolMapNameSolver nameSolver = new OrmClassToolMapNameSolver(this.ormClassToolMap);
		nameSolver.register(clazz, alias);
		nameSolver.alwaysResolveWithoutAlias(true);
		final DeleteQueryOrm delete = new DeleteQueryOrm(clazz, this.ormClassToolMap, this, this.typeFactory);
		delete.setNameSolver(nameSolver);
		return delete;
	}

	@Override
	public final ScriptExecutor scriptExecutor() throws OrmException {
		return new ScriptExecutorImpl(this);
	}

	@Override
	public final SqlExecutor sqlExecutor() {
		return new PlainSqlExecutor(this);
	}

	@Override
	public Transaction transaction(
			final TransactionDefinition transactionDefinition) throws OrmException {
		return this.sessionStrategy.getTransaction(transactionDefinition);
	}

	@Override
	public SqlPerformer sqlPerformer() throws OrmException {
		return new PlainSqlPerformer(this.sessionStrategy.sqlPerformerStrategy());
	}

	@Override
	public  T saveOrUpdate(final T object) throws OrmException {
		@SuppressWarnings("unchecked")
		final IOrmClassTool ormClassTool = (IOrmClassTool) getOrmClassToolMap().getOrmClassTool(object.getClass());

		if (ormClassTool.getOrmPersistor().hasConditionalGenerator()) {
			if(ormClassTool.getOrmPersistor().useKeyGenerators(object)) {
				return this.save(object);
			} else {
				return this.update(object);
			}
		} else {
			try {
				return this.save(object);
			} catch (OrmException e) {
				return this.update(object);
			}
		}
	}

	@Override
	public  List save(final Collection objects) throws OrmException {
		final List result = new ArrayList();
		for (final T object : objects) {
			result.add(this.save(object));
		}
		return result;
	}

	@Override
	public  List saveOrUpdate(final Collection objects) throws OrmException {
		final List result = new ArrayList();
		for (final T object : objects) {
			result.add(this.saveOrUpdate(object));
		}
		return result;
	}

	@Override
	public  List update(final Collection objects) throws OrmException {
		final List result = new ArrayList();
		for (final T object : objects) {
			result.add(this.update(object));
		}
		return result;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy