org.hibernate.engine.jdbc.cursor.internal.StandardRefCursorSupport 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
Hibernate's core ORM functionality
/*
* 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.engine.jdbc.cursor.internal;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.CallableStatement;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.service.spi.InjectService;
import org.jboss.logging.Logger;
/**
* Standard implementation of RefCursorSupport
*
* @author Steve Ebersole
*/
public class StandardRefCursorSupport implements RefCursorSupport {
private static final Logger log = Logger.getLogger( StandardRefCursorSupport.class );
private JdbcServices jdbcServices;
/**
* Hook for service registry to be able to inject JdbcServices
*
* @param jdbcServices The JdbcServices service
*/
@InjectService
@SuppressWarnings("UnusedDeclaration")
public void injectJdbcServices(JdbcServices jdbcServices) {
this.jdbcServices = jdbcServices;
}
@Override
public void registerRefCursorParameter(CallableStatement statement, int position) {
if ( jdbcServices.getExtractedMetaDataSupport().supportsRefCursors() ) {
try {
statement.registerOutParameter( position, refCursorTypeCode() );
}
catch (SQLException e) {
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error registering REF_CURSOR parameter [" + position + "]" );
}
}
else {
try {
jdbcServices.getDialect().registerResultSetOutParameter( statement, position );
}
catch (SQLException e) {
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error asking dialect to register ref cursor parameter [" + position + "]" );
}
}
}
@Override
public void registerRefCursorParameter(CallableStatement statement, String name) {
if ( jdbcServices.getExtractedMetaDataSupport().supportsRefCursors() ) {
try {
statement.registerOutParameter( name, refCursorTypeCode() );
}
catch (SQLException e) {
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error registering REF_CURSOR parameter [" + name + "]" );
}
}
else {
try {
jdbcServices.getDialect().registerResultSetOutParameter( statement, name );
}
catch (SQLException e) {
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error asking dialect to register ref cursor parameter [" + name + "]" );
}
}
}
@Override
public ResultSet getResultSet(CallableStatement statement, int position) {
if ( jdbcServices.getExtractedMetaDataSupport().supportsRefCursors() ) {
try {
return (ResultSet) getResultSetByPositionMethod().invoke( statement, position, ResultSet.class );
}
catch (InvocationTargetException e) {
if ( e.getTargetException() instanceof SQLException ) {
throw jdbcServices.getSqlExceptionHelper().convert(
(SQLException) e.getTargetException(),
"Error extracting REF_CURSOR parameter [" + position + "]"
);
}
else {
throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + position + "]", e.getTargetException() );
}
}
catch (Exception e) {
throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + position + "]", e );
}
}
else {
try {
return jdbcServices.getDialect().getResultSet( statement, position );
}
catch (SQLException e) {
throw jdbcServices.getSqlExceptionHelper().convert(
e,
"Error asking dialect to extract ResultSet from CallableStatement parameter [" + position + "]"
);
}
}
}
@Override
public ResultSet getResultSet(CallableStatement statement, String name) {
if ( jdbcServices.getExtractedMetaDataSupport().supportsRefCursors() ) {
try {
return (ResultSet) getResultSetByNameMethod().invoke( statement, name, ResultSet.class );
}
catch (InvocationTargetException e) {
if ( e.getTargetException() instanceof SQLException ) {
throw jdbcServices.getSqlExceptionHelper().convert(
(SQLException) e.getTargetException(),
"Error extracting REF_CURSOR parameter [" + name + "]"
);
}
else {
throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + name + "]", e.getTargetException() );
}
}
catch (Exception e) {
throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + name + "]", e );
}
}
else {
try {
return jdbcServices.getDialect().getResultSet( statement, name );
}
catch (SQLException e) {
throw jdbcServices.getSqlExceptionHelper().convert(
e,
"Error asking dialect to extract ResultSet from CallableStatement parameter [" + name + "]"
);
}
}
}
/**
* Does this JDBC metadata indicate that the driver defines REF_CURSOR support?
*
* @param meta The JDBC metadata
*
* @return {@code true} if the metadata indicates that the driver defines REF_CURSOR support
*/
public static boolean supportsRefCursors(DatabaseMetaData meta) {
// Standard JDBC REF_CURSOR support was not added until Java 8, so we need to use reflection to attempt to
// access these fields/methods...
try {
return (Boolean) meta.getClass().getMethod( "supportsRefCursors" ).invoke( meta );
}
catch (NoSuchMethodException e) {
log.trace( "JDBC DatabaseMetaData class does not define supportsRefCursors method..." );
}
catch (Exception e) {
log.debug( "Unexpected error trying to gauge level of JDBC REF_CURSOR support : " + e.getMessage() );
}
return false;
}
private int refCursorTypeCode() {
return Types.REF_CURSOR;
}
private static Method getResultSetByPositionMethod;
private Method getResultSetByPositionMethod() {
if ( getResultSetByPositionMethod == null ) {
try {
getResultSetByPositionMethod = CallableStatement.class.getMethod( "getObject", int.class, Class.class );
}
catch (NoSuchMethodException e) {
throw new HibernateException( "CallableStatement class does not define getObject(int,Class) method" );
}
catch (Exception e) {
throw new HibernateException( "Unexpected error trying to access CallableStatement#getObject(int,Class)" );
}
}
return getResultSetByPositionMethod;
}
private static Method getResultSetByNameMethod;
private Method getResultSetByNameMethod() {
if ( getResultSetByNameMethod == null ) {
try {
getResultSetByNameMethod = CallableStatement.class.getMethod( "getObject", String.class, Class.class );
}
catch (NoSuchMethodException e) {
throw new HibernateException( "CallableStatement class does not define getObject(String,Class) method" );
}
catch (Exception e) {
throw new HibernateException( "Unexpected error trying to access CallableStatement#getObject(String,Class)" );
}
}
return getResultSetByNameMethod;
}
}