use of org.hibernate.sql.Update in project hibernate-orm by hibernate.
the class AbstractEntityPersister method generateUpdateString.
/**
* Generate the SQL that updates a row by id (and version)
*/
protected String generateUpdateString(final boolean[] includeProperty, final int j, final Object[] oldFields, final boolean useRowId) {
Update update = new Update(getFactory().getDialect()).setTableName(getTableName(j));
// select the correct row by either pk or rowid
if (useRowId) {
//TODO: eventually, rowIdName[j]
update.addPrimaryKeyColumns(new String[] { rowIdName });
} else {
update.addPrimaryKeyColumns(getKeyColumns(j));
}
boolean hasColumns = false;
for (int i = 0; i < entityMetamodel.getPropertySpan(); i++) {
if (includeProperty[i] && isPropertyOfTable(i, j) && !lobProperties.contains(i)) {
// this is a property of the table, which we are updating
update.addColumns(getPropertyColumnNames(i), propertyColumnUpdateable[i], propertyColumnWriters[i]);
hasColumns = hasColumns || getPropertyColumnSpan(i) > 0;
}
}
// and updates. Insert them at the end.
for (int i : lobProperties) {
if (includeProperty[i] && isPropertyOfTable(i, j)) {
// this property belongs on the table and is to be inserted
update.addColumns(getPropertyColumnNames(i), propertyColumnUpdateable[i], propertyColumnWriters[i]);
hasColumns = true;
}
}
if (j == 0 && isVersioned() && entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.VERSION) {
// check it (unless this is a "generated" version column)!
if (checkVersion(includeProperty)) {
update.setVersionColumnName(getVersionColumnName());
hasColumns = true;
}
} else if (isAllOrDirtyOptLocking() && oldFields != null) {
// we are using "all" or "dirty" property-based optimistic locking
boolean[] includeInWhere = entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL ? getPropertyUpdateability() : //optimistic-lock="dirty", include all properties we are updating this time
includeProperty;
boolean[] versionability = getPropertyVersionability();
Type[] types = getPropertyTypes();
for (int i = 0; i < entityMetamodel.getPropertySpan(); i++) {
boolean include = includeInWhere[i] && isPropertyOfTable(i, j) && versionability[i];
if (include) {
// this property belongs to the table, and it is not specifically
// excluded from optimistic locking by optimistic-lock="false"
String[] propertyColumnNames = getPropertyColumnNames(i);
String[] propertyColumnWriters = getPropertyColumnWriters(i);
boolean[] propertyNullness = types[i].toColumnNullness(oldFields[i], getFactory());
for (int k = 0; k < propertyNullness.length; k++) {
if (propertyNullness[k]) {
update.addWhereColumn(propertyColumnNames[k], "=" + propertyColumnWriters[k]);
} else {
update.addWhereColumn(propertyColumnNames[k], " is null");
}
}
}
}
}
if (getFactory().getSessionFactoryOptions().isCommentsEnabled()) {
update.setComment("update " + getEntityName());
}
return hasColumns ? update.toStatementString() : null;
}
use of org.hibernate.sql.Update in project hibernate-orm by hibernate.
the class BasicCollectionPersister method generateUpdateRowString.
/**
* Generate the SQL UPDATE that updates a row
*/
@Override
protected String generateUpdateRowString() {
final Update update = new Update(getDialect()).setTableName(qualifiedTableName);
//if ( !elementIsFormula ) {
update.addColumns(elementColumnNames, elementColumnIsSettable, elementColumnWriters);
if (hasIdentifier) {
update.addPrimaryKeyColumns(new String[] { identifierColumnName });
} else if (hasIndex && !indexContainsFormula) {
update.addPrimaryKeyColumns(ArrayHelper.join(keyColumnNames, indexColumnNames));
} else {
update.addPrimaryKeyColumns(keyColumnNames);
update.addPrimaryKeyColumns(elementColumnNames, elementColumnIsInPrimaryKey, elementColumnWriters);
}
if (getFactory().getSessionFactoryOptions().isCommentsEnabled()) {
update.setComment("update collection row " + getRole());
}
return update.toStatementString();
}
use of org.hibernate.sql.Update in project hibernate-orm by hibernate.
the class PessimisticReadUpdateLockingStrategy method generateLockString.
protected String generateLockString() {
final SessionFactoryImplementor factory = lockable.getFactory();
final Update update = new Update(factory.getDialect());
update.setTableName(lockable.getRootTableName());
update.addPrimaryKeyColumns(lockable.getRootTableIdentifierColumnNames());
update.setVersionColumnName(lockable.getVersionColumnName());
update.addColumn(lockable.getVersionColumnName());
if (factory.getSessionFactoryOptions().isCommentsEnabled()) {
update.setComment(lockMode + " lock " + lockable.getEntityName());
}
return update.toStatementString();
}
use of org.hibernate.sql.Update in project hibernate-orm by hibernate.
the class PessimisticWriteUpdateLockingStrategy method generateLockString.
protected String generateLockString() {
final SessionFactoryImplementor factory = lockable.getFactory();
final Update update = new Update(factory.getDialect());
update.setTableName(lockable.getRootTableName());
update.addPrimaryKeyColumns(lockable.getRootTableIdentifierColumnNames());
update.setVersionColumnName(lockable.getVersionColumnName());
update.addColumn(lockable.getVersionColumnName());
if (factory.getSessionFactoryOptions().isCommentsEnabled()) {
update.setComment(lockMode + " lock " + lockable.getEntityName());
}
return update.toStatementString();
}
use of org.hibernate.sql.Update in project hibernate-orm by hibernate.
the class ValidityAuditStrategy method perform.
@Override
public void perform(final Session session, final String entityName, final AuditEntitiesConfiguration audEntitiesCfg, final Serializable id, final Object data, final Object revision) {
final String auditedEntityName = audEntitiesCfg.getAuditEntityName(entityName);
final String revisionInfoEntityName = audEntitiesCfg.getRevisionInfoEntityName();
// Save the audit data
session.save(auditedEntityName, data);
// Update the end date of the previous row.
//
// When application reuses identifiers of previously removed entities:
// The UPDATE statement will no-op if an entity with a given identifier has been
// inserted for the first time. But in case a deleted primary key value was
// reused, this guarantees correct strategy behavior: exactly one row with
// null end date exists for each identifier.
final boolean reuseEntityIdentifier = audEntitiesCfg.getEnversService().getGlobalConfiguration().isAllowIdentifierReuse();
if (reuseEntityIdentifier || getRevisionType(audEntitiesCfg, data) != RevisionType.ADD) {
// Register transaction completion process to guarantee execution of UPDATE statement afterQuery INSERT.
((EventSource) session).getActionQueue().registerProcess(new BeforeTransactionCompletionProcess() {
@Override
public void doBeforeTransactionCompletion(final SessionImplementor sessionImplementor) {
final Queryable productionEntityQueryable = getQueryable(entityName, sessionImplementor);
final Queryable rootProductionEntityQueryable = getQueryable(productionEntityQueryable.getRootEntityName(), sessionImplementor);
final Queryable auditedEntityQueryable = getQueryable(auditedEntityName, sessionImplementor);
final Queryable rootAuditedEntityQueryable = getQueryable(auditedEntityQueryable.getRootEntityName(), sessionImplementor);
final String updateTableName;
if (UnionSubclassEntityPersister.class.isInstance(rootProductionEntityQueryable)) {
// this is the condition causing all the problems in terms of the generated SQL UPDATE
// the problem being that we currently try to update the in-line view made up of the union query
//
// this is extremely hacky means to get the root table name for the union subclass style entities.
// hacky because it relies on internal behavior of UnionSubclassEntityPersister
// !!!!!! NOTICE - using subclass persister, not root !!!!!!
updateTableName = auditedEntityQueryable.getSubclassTableName(0);
} else {
updateTableName = rootAuditedEntityQueryable.getTableName();
}
final Type revisionInfoIdType = sessionImplementor.getFactory().getMetamodel().entityPersister(revisionInfoEntityName).getIdentifierType();
final String revEndColumnName = rootAuditedEntityQueryable.toColumns(audEntitiesCfg.getRevisionEndFieldName())[0];
final boolean isRevisionEndTimestampEnabled = audEntitiesCfg.isRevisionEndTimestampEnabled();
// update audit_ent set REVEND = ? [, REVEND_TSTMP = ?] where (prod_ent_id) = ? and REV <> ? and REVEND is null
final Update update = new Update(sessionImplementor.getFactory().getJdbcServices().getDialect()).setTableName(updateTableName);
// set REVEND = ?
update.addColumn(revEndColumnName);
// set [, REVEND_TSTMP = ?]
if (isRevisionEndTimestampEnabled) {
update.addColumn(rootAuditedEntityQueryable.toColumns(audEntitiesCfg.getRevisionEndTimestampFieldName())[0]);
}
// where (prod_ent_id) = ?
update.addPrimaryKeyColumns(rootProductionEntityQueryable.getIdentifierColumnNames());
// where REV <> ?
update.addWhereColumn(rootAuditedEntityQueryable.toColumns(audEntitiesCfg.getRevisionNumberPath())[0], "<> ?");
// where REVEND is null
update.addWhereColumn(revEndColumnName, " is null");
// Now lets execute the sql...
final String updateSql = update.toStatementString();
int rowCount = sessionImplementor.doReturningWork(new ReturningWork<Integer>() {
@Override
public Integer execute(Connection connection) throws SQLException {
PreparedStatement preparedStatement = sessionImplementor.getJdbcCoordinator().getStatementPreparer().prepareStatement(updateSql);
try {
int index = 1;
// set REVEND = ?
final Number revisionNumber = audEntitiesCfg.getEnversService().getRevisionInfoNumberReader().getRevisionNumber(revision);
revisionInfoIdType.nullSafeSet(preparedStatement, revisionNumber, index, sessionImplementor);
index += revisionInfoIdType.getColumnSpan(sessionImplementor.getFactory());
// set [, REVEND_TSTMP = ?]
if (isRevisionEndTimestampEnabled) {
final Object revEndTimestampObj = revisionTimestampGetter.get(revision);
final Date revisionEndTimestamp = convertRevEndTimestampToDate(revEndTimestampObj);
final Type revEndTsType = rootAuditedEntityQueryable.getPropertyType(audEntitiesCfg.getRevisionEndTimestampFieldName());
revEndTsType.nullSafeSet(preparedStatement, revisionEndTimestamp, index, sessionImplementor);
index += revEndTsType.getColumnSpan(sessionImplementor.getFactory());
}
// where (prod_ent_id) = ?
final Type idType = rootProductionEntityQueryable.getIdentifierType();
idType.nullSafeSet(preparedStatement, id, index, sessionImplementor);
index += idType.getColumnSpan(sessionImplementor.getFactory());
// where REV <> ?
final Type revType = rootAuditedEntityQueryable.getPropertyType(audEntitiesCfg.getRevisionNumberPath());
revType.nullSafeSet(preparedStatement, revisionNumber, index, sessionImplementor);
return sessionImplementor.getJdbcCoordinator().getResultSetReturn().executeUpdate(preparedStatement);
} finally {
sessionImplementor.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release(preparedStatement);
sessionImplementor.getJdbcCoordinator().afterStatementExecution();
}
}
});
if (rowCount != 1 && (!reuseEntityIdentifier || (getRevisionType(audEntitiesCfg, data) != RevisionType.ADD))) {
throw new RuntimeException("Cannot update previous revision for entity " + auditedEntityName + " and id " + id);
}
}
});
}
sessionCacheCleaner.scheduleAuditDataRemoval(session, data);
}
Aggregations