org.hibernate.hql.spi.id.inline.AbstractInlineIdsUpdateHandlerImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
The core O/RM functionality as provided by Hibernate
The newest version!
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.hql.spi.id.inline;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.hql.internal.ast.HqlSqlWalker;
import org.hibernate.hql.internal.ast.tree.AssignmentSpecification;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.param.ParameterSpecification;
import org.hibernate.sql.Update;
/**
* Inline bulk-id delete handler that selects the identifiers of the rows to be deleted.
*
* @author Vlad Mihalcea
*/
public abstract class AbstractInlineIdsUpdateHandlerImpl
extends AbstractInlineIdsBulkIdHandler
implements MultiTableBulkIdStrategy.UpdateHandler {
private final Map updates = new LinkedHashMap<>();
private ParameterSpecification[][] assignmentParameterSpecifications;
public AbstractInlineIdsUpdateHandlerImpl(
SessionFactoryImplementor factory,
HqlSqlWalker walker) {
super( factory, walker );
}
@Override
public String[] getSqlStatements() {
return updates.values().toArray( new String[updates.values().size()] );
}
@Override
public int execute(
SharedSessionContractImplementor session,
QueryParameters queryParameters) {
IdsClauseBuilder values = prepareInlineStatement( session, queryParameters );
if ( !values.getIds().isEmpty() ) {
String[] tableNames = getTargetedQueryable().getConstraintOrderedTableNameClosure();
String[][] columnNames = getTargetedQueryable().getContraintOrderedTableKeyColumnClosure();
String idSubselect = values.toStatement();
assignmentParameterSpecifications = new ParameterSpecification[tableNames.length][];
for ( int tableIndex = 0; tableIndex < tableNames.length; tableIndex++ ) {
boolean affected = false;
final List parameterList = new ArrayList<>();
Update update = generateUpdate( tableNames[tableIndex], columnNames[tableIndex], idSubselect, "bulk update" );
final List assignmentSpecifications = walker().getAssignmentSpecifications();
for ( AssignmentSpecification assignmentSpecification : assignmentSpecifications ) {
if ( assignmentSpecification.affectsTable( tableNames[tableIndex] ) ) {
affected = true;
update.appendAssignmentFragment( assignmentSpecification.getSqlAssignmentFragment() );
if ( assignmentSpecification.getParameters() != null ) {
Collections.addAll( parameterList, assignmentSpecification.getParameters() );
}
}
}
if ( affected ) {
updates.put( tableIndex, update.toStatementString() );
assignmentParameterSpecifications[tableIndex] = parameterList.toArray( new ParameterSpecification[parameterList.size()] );
}
}
// Start performing the updates
for ( Map.Entry updateEntry: updates.entrySet()) {
int i = updateEntry.getKey();
String update = updateEntry.getValue();
if ( update == null) {
continue;
}
try {
try (PreparedStatement ps = session
.getJdbcCoordinator().getStatementPreparer()
.prepareStatement( update, false )) {
int position = 1; // jdbc params are 1-based
if ( assignmentParameterSpecifications[i] != null ) {
for ( int x = 0; x < assignmentParameterSpecifications[i].length; x++ ) {
position += assignmentParameterSpecifications[i][x]
.bind( ps, queryParameters, session, position );
}
}
session
.getJdbcCoordinator().getResultSetReturn()
.executeUpdate( ps );
}
}
catch ( SQLException e ) {
throw convert(
e,
"error performing bulk update",
update
);
}
}
}
return values.getIds().size();
}
protected Update generateUpdate(
String tableName,
String[] columnNames,
String idSubselect,
String comment) {
final Update update = new Update( factory().getServiceRegistry().getService( JdbcServices.class ).getDialect() )
.setTableName( tableName )
.setWhere( "(" + String.join( ", ", (CharSequence[]) columnNames ) + ") in (" + idSubselect + ")" );
if ( factory().getSessionFactoryOptions().isCommentsEnabled() ) {
update.setComment( comment );
}
return update;
}
}