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

org.hibernate.internal.IteratorImpl 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.internal;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.NoSuchElementException;

import org.hibernate.HibernateException;
import org.hibernate.JDBCException;
import org.hibernate.engine.HibernateIterator;
import org.hibernate.event.spi.EventSource;
import org.hibernate.hql.internal.HolderInstantiator;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;

/**
 * An implementation of java.util.Iterator that is
 * returned by iterate() query execution methods.
 *
 * @author Gavin King
 */
public final class IteratorImpl implements HibernateIterator {
	private static final CoreMessageLogger LOG = CoreLogging.messageLogger( IteratorImpl.class );

	private ResultSet rs;
	private final EventSource session;
	private boolean readOnly;
	private final Type[] types;
	private final boolean single;
	private Object currentResult;
	private boolean hasNext;
	private final String[][] names;
	private PreparedStatement ps;
	private HolderInstantiator holderInstantiator;

	public IteratorImpl(
			ResultSet rs,
			PreparedStatement ps,
			EventSource sess,
			boolean readOnly,
			Type[] types,
			String[][] columnNames,
			HolderInstantiator holderInstantiator) throws HibernateException, SQLException {
		this.rs = rs;
		this.ps = ps;
		this.session = sess;
		this.readOnly = readOnly;
		this.types = types;
		this.names = columnNames;
		this.holderInstantiator = holderInstantiator;

		single = types.length == 1;

		postNext();
	}

	public void close() throws JDBCException {
		if ( ps != null ) {
			LOG.debug( "Closing iterator" );
			session.getJdbcCoordinator().getResourceRegistry().release( ps );
			try {
				session.getPersistenceContext().getLoadContexts().cleanup( rs );
			}
			catch (Throwable ignore) {
				// ignore this error for now
				LOG.debugf( "Exception trying to cleanup load context : %s", ignore.getMessage() );
			}
			session.getJdbcCoordinator().afterStatementExecution();
			ps = null;
			rs = null;
			hasNext = false;
		}
	}

	private void postNext() throws SQLException {
		LOG.debug( "Attempting to retrieve next results" );
		this.hasNext = rs.next();
		if ( !hasNext ) {
			LOG.debug( "Exhausted results" );
			close();
		}
		else {
			LOG.debug( "Retrieved next results" );
		}
	}

	public boolean hasNext() {
		return hasNext;
	}

	public Object next() throws HibernateException {
		if ( !hasNext ) {
			throw new NoSuchElementException( "No more results" );
		}
		boolean sessionDefaultReadOnlyOrig = session.isDefaultReadOnly();
		session.setDefaultReadOnly( readOnly );
		try {
			boolean isHolder = holderInstantiator.isRequired();

			LOG.debugf( "Assembling results" );
			if ( single && !isHolder ) {
				currentResult = types[0].nullSafeGet( rs, names[0], session, null );
			}
			else {
				Object[] currentResults = new Object[types.length];
				for ( int i = 0; i < types.length; i++ ) {
					currentResults[i] = types[i].nullSafeGet( rs, names[i], session, null );
				}

				if ( isHolder ) {
					currentResult = holderInstantiator.instantiate( currentResults );
				}
				else {
					currentResult = currentResults;
				}
			}

			postNext();
			LOG.debugf( "Returning current results" );
			return currentResult;
		}
		catch (SQLException sqle) {
			throw session.getFactory().getSQLExceptionHelper().convert(
					sqle,
					"could not get next iterator result"
			);
		}
		finally {
			session.setDefaultReadOnly( sessionDefaultReadOnlyOrig );
		}
	}

	public void remove() {
		if ( !single ) {
			throw new UnsupportedOperationException( "Not a single column hibernate query result set" );
		}
		if ( currentResult == null ) {
			throw new IllegalStateException( "Called Iterator.remove() beforeQuery next()" );
		}
		if ( !( types[0] instanceof EntityType ) ) {
			throw new UnsupportedOperationException( "Not an entity" );
		}

		session.delete(
				( (EntityType) types[0] ).getAssociatedEntityName(),
				currentResult,
				false,
				null
		);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy