com.jpattern.orm.session.OrmSession Maven / Gradle / Ivy
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