/*
 * 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.hql.spi.id.local;

import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.boot.spi.MetadataBuildingOptions;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
import org.hibernate.engine.jdbc.spi.JdbcServices;
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.DeleteStatement;
import org.hibernate.hql.internal.ast.tree.FromElement;
import org.hibernate.hql.internal.ast.tree.UpdateStatement;
import org.hibernate.hql.spi.id.AbstractMultiTableBulkIdStrategyImpl;
import org.hibernate.hql.spi.id.AbstractMultiTableBulkIdStrategyImpl.PreparationContext;
import org.hibernate.hql.spi.id.IdTableSupport;
import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.TableBasedDeleteHandlerImpl;
import org.hibernate.hql.spi.id.TableBasedUpdateHandlerImpl;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Table;
import org.hibernate.persister.entity.Queryable;

Strategy based on ANSI SQL's definition of a "local temporary table" (local to each db session).
Author:Steve Ebersole
/** * Strategy based on ANSI SQL's definition of a "local temporary table" (local to each db session). * * @author Steve Ebersole */
public class LocalTemporaryTableBulkIdStrategy extends AbstractMultiTableBulkIdStrategyImpl<IdTableInfoImpl, PreparationContext> implements MultiTableBulkIdStrategy { public static final String SHORT_NAME = "local_temporary"; private final AfterUseAction afterUseAction; private TempTableDdlTransactionHandling ddlTransactionHandling; public LocalTemporaryTableBulkIdStrategy() { this( new IdTableSupportStandardImpl() { @Override public String getCreateIdTableCommand() { return "create local temporary table"; } }, AfterUseAction.DROP, null ); } public LocalTemporaryTableBulkIdStrategy( IdTableSupport idTableSupport, AfterUseAction afterUseAction, TempTableDdlTransactionHandling ddlTransactionHandling) { super( idTableSupport ); this.afterUseAction = afterUseAction; this.ddlTransactionHandling = ddlTransactionHandling; } @Override protected void initialize(MetadataBuildingOptions buildingOptions, SessionFactoryOptions sessionFactoryOptions) { if ( ddlTransactionHandling == null ) { ddlTransactionHandling = sessionFactoryOptions.getTempTableDdlTransactionHandling(); } } @Override protected IdTableInfoImpl buildIdTableInfo( PersistentClass entityBinding, Table idTable, JdbcServices jdbcServices, MetadataImplementor metadata, PreparationContext context) { return new IdTableInfoImpl( jdbcServices.getJdbcEnvironment().getQualifiedObjectNameFormatter().format( idTable.getQualifiedTableName(), jdbcServices.getJdbcEnvironment().getDialect() ), buildIdTableCreateStatement( idTable, jdbcServices, metadata ), buildIdTableDropStatement( idTable, jdbcServices ) ); } @Override public void release(JdbcServices jdbcServices, JdbcConnectionAccess connectionAccess) { // nothing to do } @Override public UpdateHandler buildUpdateHandler(SessionFactoryImplementor factory, HqlSqlWalker walker) { final UpdateStatement updateStatement = (UpdateStatement) walker.getAST(); final FromElement fromElement = updateStatement.getFromClause().getFromElement(); final Queryable targetedPersister = fromElement.getQueryable(); final IdTableInfoImpl tableInfo = getIdTableInfo( targetedPersister ); return new TableBasedUpdateHandlerImpl( factory, walker, tableInfo ) { @Override protected void prepareForUse(Queryable persister, SharedSessionContractImplementor session) { Helper.INSTANCE.createTempTable( tableInfo, ddlTransactionHandling, session ); } @Override protected void releaseFromUse(Queryable persister, SharedSessionContractImplementor session) { Helper.INSTANCE.releaseTempTable( tableInfo, afterUseAction, ddlTransactionHandling, session ); } }; } @Override public DeleteHandler buildDeleteHandler(SessionFactoryImplementor factory, HqlSqlWalker walker) { final DeleteStatement updateStatement = (DeleteStatement) walker.getAST(); final FromElement fromElement = updateStatement.getFromClause().getFromElement(); final Queryable targetedPersister = fromElement.getQueryable(); final IdTableInfoImpl tableInfo = getIdTableInfo( targetedPersister ); return new TableBasedDeleteHandlerImpl( factory, walker, tableInfo ) { @Override protected void prepareForUse(Queryable persister, SharedSessionContractImplementor session) { Helper.INSTANCE.createTempTable( tableInfo, ddlTransactionHandling, session ); } @Override protected void releaseFromUse(Queryable persister, SharedSessionContractImplementor session) { Helper.INSTANCE.releaseTempTable( tableInfo, afterUseAction, ddlTransactionHandling, session ); } }; } }