All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.hql.spi.id.persistent.PersistentTableBulkIdStrategy Maven / Gradle / Ivy

There is a newer version: 7.0.0.Alpha1
Show 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.persistent;

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.QualifiedTableName;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.spi.MetadataBuildingOptions;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.config.spi.StandardConverters;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
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.IdTableHelper;
import org.hibernate.hql.spi.id.IdTableSupport;
import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Table;
import org.hibernate.persister.entity.Queryable;

/**
 * This is a strategy that mimics temporary tables for databases which do not support
 * temporary tables.  It follows a pattern similar to the ANSI SQL definition of global
 * temporary table using a "session id" column to segment rows from the various sessions.
 *
 * @author Steve Ebersole
 */
public class PersistentTableBulkIdStrategy
		extends AbstractMultiTableBulkIdStrategyImpl
		implements MultiTableBulkIdStrategy {

	public static final String SHORT_NAME = "persistent";

	public static final String DROP_ID_TABLES = "hibernate.hql.bulk_id_strategy.persistent.drop_tables";
	public static final String SCHEMA = "hibernate.hql.bulk_id_strategy.persistent.schema";
	public static final String CATALOG = "hibernate.hql.bulk_id_strategy.persistent.catalog";

	private Identifier catalog;
	private Identifier schema;

	private boolean dropIdTables;
	private String[] dropTableStatements;

	public PersistentTableBulkIdStrategy() {
		this( IdTableSupportStandardImpl.INSTANCE );
	}

	public PersistentTableBulkIdStrategy(IdTableSupport idTableSupport) {
		super( idTableSupport );
	}

	@Override
	protected PreparationContextImpl buildPreparationContext() {
		return new PreparationContextImpl();
	}

	@Override
	protected void initialize(MetadataBuildingOptions buildingOptions, SessionFactoryOptions sessionFactoryOptions) {
		final StandardServiceRegistry serviceRegistry = buildingOptions.getServiceRegistry();
		final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
		final ConfigurationService configService = serviceRegistry.getService( ConfigurationService.class );

		final String catalogName = configService.getSetting(
				CATALOG,
				StandardConverters.STRING,
				configService.getSetting( AvailableSettings.DEFAULT_CATALOG, StandardConverters.STRING )
		);
		final String schemaName = configService.getSetting(
				SCHEMA,
				StandardConverters.STRING,
				configService.getSetting( AvailableSettings.DEFAULT_SCHEMA, StandardConverters.STRING )
		);

		this.catalog = jdbcEnvironment.getIdentifierHelper().toIdentifier( catalogName );
		this.schema = jdbcEnvironment.getIdentifierHelper().toIdentifier( schemaName );

		this.dropIdTables = configService.getSetting(
				DROP_ID_TABLES,
				StandardConverters.BOOLEAN,
				false
		);
	}

	@Override
	protected QualifiedTableName determineIdTableName(
			JdbcEnvironment jdbcEnvironment,
			PersistentClass entityBinding) {
		return new QualifiedTableName(
				catalog,
				schema,
				super.determineIdTableName( jdbcEnvironment, entityBinding ).getTableName()
		);
	}

	@Override
	protected void augmentIdTableDefinition(Table idTable) {
		Column sessionIdColumn = new Column( Helper.SESSION_ID_COLUMN_NAME );
		sessionIdColumn.setSqlType( "CHAR(36)" );
		sessionIdColumn.setComment( "Used to hold the Hibernate Session identifier" );
		idTable.addColumn( sessionIdColumn );
	}

	@Override
	protected IdTableInfoImpl buildIdTableInfo(
			PersistentClass entityBinding,
			Table idTable,
			JdbcServices jdbcServices,
			MetadataImplementor metadata,
			PreparationContextImpl context) {
		final String renderedName = jdbcServices.getJdbcEnvironment().getQualifiedObjectNameFormatter().format(
				idTable.getQualifiedTableName(),
				jdbcServices.getJdbcEnvironment().getDialect()
		);

		context.creationStatements.add( buildIdTableCreateStatement( idTable, jdbcServices, metadata ) );
		if ( dropIdTables ) {
			context.dropStatements.add( buildIdTableDropStatement( idTable, jdbcServices ) );
		}

		return new IdTableInfoImpl( renderedName );
	}

	@Override
	protected void finishPreparation(
			JdbcServices jdbcServices,
			JdbcConnectionAccess connectionAccess,
			MetadataImplementor metadata,
			PreparationContextImpl context) {
		IdTableHelper.INSTANCE.executeIdTableCreationStatements(
				context.creationStatements,
				jdbcServices,
				connectionAccess
		);

		this.dropTableStatements = dropIdTables
				? context.dropStatements.toArray( new String[ context.dropStatements.size() ] )
				: null;
	}

	@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();

		return new UpdateHandlerImpl(
				factory,
				walker,
				getIdTableInfo( targetedPersister )
		);
	}

	@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();

		return new DeleteHandlerImpl(
				factory,
				walker,
				getIdTableInfo( targetedPersister )
		);
	}

	@Override
	public void release(JdbcServices jdbcServices, JdbcConnectionAccess connectionAccess) {
		if ( ! dropIdTables ) {
			return;
		}

		IdTableHelper.INSTANCE.executeIdTableDropStatements( dropTableStatements, jdbcServices, connectionAccess );
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy