org.dbflute.s2dao.sqlhandler.TnAbstractEntityHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dbflute-runtime Show documentation
Show all versions of dbflute-runtime Show documentation
The runtime library of DBFlute
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.dbflute.s2dao.sqlhandler;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.sql.DataSource;
import org.dbflute.Entity;
import org.dbflute.bhv.core.context.ResourceContext;
import org.dbflute.bhv.writable.DeleteOption;
import org.dbflute.bhv.writable.InsertOption;
import org.dbflute.bhv.writable.UpdateOption;
import org.dbflute.cbean.ConditionBean;
import org.dbflute.exception.EntityAlreadyUpdatedException;
import org.dbflute.helper.beans.DfPropertyDesc;
import org.dbflute.jdbc.StatementFactory;
import org.dbflute.jdbc.ValueType;
import org.dbflute.s2dao.identity.TnIdentityGenerationHandler;
import org.dbflute.s2dao.metadata.TnBeanMetaData;
import org.dbflute.s2dao.metadata.TnPropertyType;
import org.dbflute.util.DfCollectionUtil;
import org.dbflute.util.DfTypeUtil;
/**
* @author modified by jflute (originated in S2Dao)
*/
public abstract class TnAbstractEntityHandler extends TnAbstractBasicSqlHandler {
// ===================================================================================
// Attribute
// =========
protected final TnBeanMetaData _beanMetaData;
protected final TnPropertyType[] _boundPropTypes; // not only completely bounds (needs to filter)
protected boolean _optimisticLockHandling;
protected boolean _versionNoAutoIncrementOnMemory; // to adjust binding
protected InsertOption extends ConditionBean> _insertOption;
protected UpdateOption extends ConditionBean> _updateOption;
protected DeleteOption extends ConditionBean> _deleteOption;
protected Object[] _bindVariables;
protected ValueType[] _bindVariableValueTypes;
protected List _newTimestampList;
protected List _newVersionNoList;
// ===================================================================================
// Constructor
// ===========
public TnAbstractEntityHandler(DataSource dataSource, StatementFactory statementFactory, String sql, TnBeanMetaData beanMetaData,
TnPropertyType[] boundPropTypes) {
super(dataSource, statementFactory, sql);
assertObjectNotNull("beanMetaData", beanMetaData);
assertObjectNotNull("boundPropTypes", boundPropTypes); // not null but empty allowed
_beanMetaData = beanMetaData;
_boundPropTypes = boundPropTypes;
}
// ===================================================================================
// Execute
// =======
public int execute(Object[] args) {
final Connection conn = getConnection();
try {
return execute(conn, args[0]);
} finally {
close(conn);
}
}
protected int execute(Connection conn, Object bean) {
processBefore(conn, bean);
setupBindVariables(bean);
logSql(_bindVariables, getArgTypes(_bindVariables));
final PreparedStatement ps = prepareStatement(conn);
RuntimeException sqlEx = null;
final int ret;
try {
bindArgs(conn, ps, _bindVariables, _bindVariableValueTypes);
ret = executeUpdate(ps);
handleUpdateResultWithOptimisticLock(bean, ret);
} catch (RuntimeException e) {
// not only SQLFailureException because the JDBC wrapper may throw an other exception
sqlEx = e;
throw e;
} finally {
close(ps);
processFinally(conn, bean, sqlEx);
}
// a value of exclusive control column should be synchronized
// after handling optimistic lock
processSuccess(conn, bean, ret);
return ret;
}
// ===================================================================================
// Extension Process
// =================
protected void processBefore(Connection conn, Object bean) {
}
protected void processFinally(Connection conn, Object bean, RuntimeException sqlEx) {
}
protected void processSuccess(Connection conn, Object bean, int ret) {
}
// ===================================================================================
// Optimistic Lock
// ===============
protected void handleUpdateResultWithOptimisticLock(Object bean, int ret) {
if (_optimisticLockHandling && ret < 1) { // means no update (contains minus just in case)
throw createEntityAlreadyUpdatedException(bean, ret);
}
}
protected EntityAlreadyUpdatedException createEntityAlreadyUpdatedException(Object bean, int rows) {
return new EntityAlreadyUpdatedException(bean, rows);
}
// ===================================================================================
// Bind Variable
// =============
protected abstract void setupBindVariables(Object bean);
protected void setupInsertBindVariables(Object bean) {
final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy