HHH-8415 - Throw exception types expected by JPA spec wrt StoredProcedureQuery
This commit is contained in:
parent
aea6b767ae
commit
6beb5acb4b
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.procedure;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class NoSuchParameterException extends HibernateException {
|
||||||
|
public NoSuchParameterException(String message) {
|
||||||
|
super( message );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.procedure;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ParameterStrategyException extends HibernateException {
|
||||||
|
public ParameterStrategyException(String message) {
|
||||||
|
super( message );
|
||||||
|
}
|
||||||
|
}
|
|
@ -82,6 +82,9 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
|
||||||
* @param position The parameter position
|
* @param position The parameter position
|
||||||
*
|
*
|
||||||
* @return The parameter registration memento
|
* @return The parameter registration memento
|
||||||
|
*
|
||||||
|
* @throws ParameterStrategyException If the ProcedureCall is defined using named parameters
|
||||||
|
* @throws NoSuchParameterException If no parameter with that position exists
|
||||||
*/
|
*/
|
||||||
public ParameterRegistration getParameterRegistration(int position);
|
public ParameterRegistration getParameterRegistration(int position);
|
||||||
|
|
||||||
|
@ -122,6 +125,9 @@ public interface ProcedureCall extends BasicQueryContract, SynchronizeableQuery
|
||||||
* @param name The parameter name
|
* @param name The parameter name
|
||||||
*
|
*
|
||||||
* @return The parameter registration memento
|
* @return The parameter registration memento
|
||||||
|
*
|
||||||
|
* @throws ParameterStrategyException If the ProcedureCall is defined using positional parameters
|
||||||
|
* @throws NoSuchParameterException If no parameter with that name exists
|
||||||
*/
|
*/
|
||||||
public ParameterRegistration getParameterRegistration(String name);
|
public ParameterRegistration getParameterRegistration(String name);
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,9 @@ public interface ProcedureOutputs extends Outputs {
|
||||||
*
|
*
|
||||||
* @return The output value.
|
* @return The output value.
|
||||||
*
|
*
|
||||||
|
* @throws ParameterStrategyException If the ProcedureCall is defined using positional parameters
|
||||||
|
* @throws NoSuchParameterException If no parameter with that name exists
|
||||||
|
*
|
||||||
* @see ProcedureCall#registerParameter(String, Class, javax.persistence.ParameterMode)
|
* @see ProcedureCall#registerParameter(String, Class, javax.persistence.ParameterMode)
|
||||||
*/
|
*/
|
||||||
public Object getOutputParameterValue(String name);
|
public Object getOutputParameterValue(String name);
|
||||||
|
@ -64,6 +67,9 @@ public interface ProcedureOutputs extends Outputs {
|
||||||
*
|
*
|
||||||
* @return The output value.
|
* @return The output value.
|
||||||
*
|
*
|
||||||
|
* @throws ParameterStrategyException If the ProcedureCall is defined using named parameters
|
||||||
|
* @throws NoSuchParameterException If no parameter with that position exists
|
||||||
|
*
|
||||||
* @see ProcedureCall#registerParameter(int, Class, javax.persistence.ParameterMode)
|
* @see ProcedureCall#registerParameter(int, Class, javax.persistence.ParameterMode)
|
||||||
*/
|
*/
|
||||||
public Object getOutputParameterValue(int position);
|
public Object getOutputParameterValue(int position);
|
||||||
|
|
|
@ -50,7 +50,9 @@ import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.procedure.NamedParametersNotSupportedException;
|
import org.hibernate.procedure.NamedParametersNotSupportedException;
|
||||||
|
import org.hibernate.procedure.NoSuchParameterException;
|
||||||
import org.hibernate.procedure.ParameterRegistration;
|
import org.hibernate.procedure.ParameterRegistration;
|
||||||
|
import org.hibernate.procedure.ParameterStrategyException;
|
||||||
import org.hibernate.procedure.ProcedureCall;
|
import org.hibernate.procedure.ProcedureCall;
|
||||||
import org.hibernate.procedure.ProcedureCallMemento;
|
import org.hibernate.procedure.ProcedureCallMemento;
|
||||||
import org.hibernate.procedure.ProcedureOutputs;
|
import org.hibernate.procedure.ProcedureOutputs;
|
||||||
|
@ -321,21 +323,22 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
||||||
@Override
|
@Override
|
||||||
public ParameterRegistrationImplementor getParameterRegistration(int position) {
|
public ParameterRegistrationImplementor getParameterRegistration(int position) {
|
||||||
if ( parameterStrategy != ParameterStrategy.POSITIONAL ) {
|
if ( parameterStrategy != ParameterStrategy.POSITIONAL ) {
|
||||||
throw new IllegalArgumentException( "Positions were not used to register parameters with this stored procedure call" );
|
throw new ParameterStrategyException(
|
||||||
|
"Attempt to access positional parameter [" + position + "] but ProcedureCall using named parameters"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
try {
|
for ( ParameterRegistrationImplementor parameter : registeredParameters ) {
|
||||||
return registeredParameters.get( position );
|
if ( position == parameter.getPosition() ) {
|
||||||
|
return parameter;
|
||||||
}
|
}
|
||||||
catch ( Exception e ) {
|
|
||||||
throw new QueryException( "Could not locate parameter registered using that position [" + position + "]" );
|
|
||||||
}
|
}
|
||||||
|
throw new NoSuchParameterException( "Could not locate parameter registered using that position [" + position + "]" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> ParameterRegistration<T> registerParameter(String name, Class<T> type, ParameterMode mode) {
|
public <T> ParameterRegistration<T> registerParameter(String name, Class<T> type, ParameterMode mode) {
|
||||||
final NamedParameterRegistration parameterRegistration
|
final NamedParameterRegistration parameterRegistration = new NamedParameterRegistration( this, name, mode, type );
|
||||||
= new NamedParameterRegistration( this, name, mode, type );
|
|
||||||
registerParameter( parameterRegistration );
|
registerParameter( parameterRegistration );
|
||||||
return parameterRegistration;
|
return parameterRegistration;
|
||||||
}
|
}
|
||||||
|
@ -350,14 +353,14 @@ public class ProcedureCallImpl extends AbstractBasicQueryContractImpl implements
|
||||||
@Override
|
@Override
|
||||||
public ParameterRegistrationImplementor getParameterRegistration(String name) {
|
public ParameterRegistrationImplementor getParameterRegistration(String name) {
|
||||||
if ( parameterStrategy != ParameterStrategy.NAMED ) {
|
if ( parameterStrategy != ParameterStrategy.NAMED ) {
|
||||||
throw new IllegalArgumentException( "Names were not used to register parameters with this stored procedure call" );
|
throw new ParameterStrategyException( "Names were not used to register parameters with this stored procedure call" );
|
||||||
}
|
}
|
||||||
for ( ParameterRegistrationImplementor parameter : registeredParameters ) {
|
for ( ParameterRegistrationImplementor parameter : registeredParameters ) {
|
||||||
if ( name.equals( parameter.getName() ) ) {
|
if ( name.equals( parameter.getName() ) ) {
|
||||||
return parameter;
|
return parameter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException( "Could not locate parameter registered under that name [" + name + "]" );
|
throw new NoSuchParameterException( "Could not locate parameter registered under that name [" + name + "]" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class ProcedureOutputsImpl extends OutputsImpl implements ProcedureOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CurrentReturnState buildCurrentReturnDescriptor(boolean isResultSet, int updateCount) {
|
protected CurrentReturnState buildCurrentReturnState(boolean isResultSet, int updateCount) {
|
||||||
return new ProcedureCurrentReturnState( isResultSet, updateCount, refCursorParamIndex );
|
return new ProcedureCurrentReturnState( isResultSet, updateCount, refCursorParamIndex );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,8 +81,8 @@ public class ProcedureOutputsImpl extends OutputsImpl implements ProcedureOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean indicatesMoreReturns() {
|
public boolean indicatesMoreOutputs() {
|
||||||
return super.indicatesMoreReturns()
|
return super.indicatesMoreOutputs()
|
||||||
|| ProcedureOutputsImpl.this.refCursorParamIndex < ProcedureOutputsImpl.this.refCursorParameters.length;
|
|| ProcedureOutputsImpl.this.refCursorParamIndex < ProcedureOutputsImpl.this.refCursorParameters.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ public class ProcedureOutputsImpl extends OutputsImpl implements ProcedureOutput
|
||||||
.getService( RefCursorSupport.class )
|
.getService( RefCursorSupport.class )
|
||||||
.getResultSet( ProcedureOutputsImpl.this.callableStatement, refCursorParam.getPosition() );
|
.getResultSet( ProcedureOutputsImpl.this.callableStatement, refCursorParam.getPosition() );
|
||||||
}
|
}
|
||||||
return new ResultSetOutputImpl( extractResults( resultSet ) );
|
return buildResultSetOutput( extractResults( resultSet ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,23 +38,18 @@ public interface Outputs {
|
||||||
*
|
*
|
||||||
* @return The current Output object. Can be {@code null}
|
* @return The current Output object. Can be {@code null}
|
||||||
*/
|
*/
|
||||||
public Output getCurrentOutput();
|
public Output getCurrent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Are there any more Output objects associated with {@code this}?
|
* Go to the next Output object (if any), returning an indication of whether there was another (aka, will
|
||||||
|
* the next call to {@link #getCurrent()} return {@code null}?
|
||||||
*
|
*
|
||||||
* @return {@code true} means there are more Output objects available via {@link #getNextOutput()}; {@code false}
|
* @return {@code true} if the next call to {@link #getCurrent()} will return a non-{@code null} value.
|
||||||
* indicates that calling {@link #getNextOutput()} will certainly result in an exception.
|
|
||||||
*/
|
*/
|
||||||
public boolean hasMoreOutput();
|
public boolean goToNext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the next return
|
* Eagerly release any resources held by this Outputs.
|
||||||
*
|
|
||||||
* @return The next return.
|
|
||||||
*
|
|
||||||
* @throws NoMoreReturnsException Thrown if there are no more returns associated with this Result, as would
|
|
||||||
* have been indicated by a {@code false} return from {@link #hasMoreOutput()}.
|
|
||||||
*/
|
*/
|
||||||
public Output getNextOutput() throws NoMoreReturnsException;
|
public void release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,9 +43,7 @@ import org.hibernate.loader.custom.sql.SQLQueryReturnProcessor;
|
||||||
import org.hibernate.loader.spi.AfterLoadAction;
|
import org.hibernate.loader.spi.AfterLoadAction;
|
||||||
import org.hibernate.result.NoMoreReturnsException;
|
import org.hibernate.result.NoMoreReturnsException;
|
||||||
import org.hibernate.result.Outputs;
|
import org.hibernate.result.Outputs;
|
||||||
import org.hibernate.result.ResultSetOutput;
|
|
||||||
import org.hibernate.result.Output;
|
import org.hibernate.result.Output;
|
||||||
import org.hibernate.result.UpdateCountOutput;
|
|
||||||
import org.hibernate.result.spi.ResultContext;
|
import org.hibernate.result.spi.ResultContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,14 +67,14 @@ public class OutputsImpl implements Outputs {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final boolean isResultSet = jdbcStatement.execute();
|
final boolean isResultSet = jdbcStatement.execute();
|
||||||
currentReturnState = buildCurrentReturnDescriptor( isResultSet );
|
currentReturnState = buildCurrentReturnState( isResultSet );
|
||||||
}
|
}
|
||||||
catch (SQLException e) {
|
catch (SQLException e) {
|
||||||
throw convert( e, "Error calling CallableStatement.getMoreResults" );
|
throw convert( e, "Error calling CallableStatement.getMoreResults" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CurrentReturnState buildCurrentReturnDescriptor(boolean isResultSet) {
|
private CurrentReturnState buildCurrentReturnState(boolean isResultSet) {
|
||||||
int updateCount = -1;
|
int updateCount = -1;
|
||||||
if ( ! isResultSet ) {
|
if ( ! isResultSet ) {
|
||||||
try {
|
try {
|
||||||
|
@ -87,42 +85,57 @@ public class OutputsImpl implements Outputs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildCurrentReturnDescriptor( isResultSet, updateCount );
|
return buildCurrentReturnState( isResultSet, updateCount );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CurrentReturnState buildCurrentReturnDescriptor(boolean isResultSet, int updateCount) {
|
protected CurrentReturnState buildCurrentReturnState(boolean isResultSet, int updateCount) {
|
||||||
return new CurrentReturnState( isResultSet, updateCount );
|
return new CurrentReturnState( isResultSet, updateCount );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected JDBCException convert(SQLException e, String message) {
|
||||||
public Output getCurrentOutput() {
|
return context.getSession().getFactory().getSQLExceptionHelper().convert(
|
||||||
if ( currentReturnState == null ) {
|
e,
|
||||||
return null;
|
message,
|
||||||
}
|
context.getSql()
|
||||||
return currentReturnState.getReturn();
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasMoreOutput() {
|
public Output getCurrent() {
|
||||||
|
if ( currentReturnState == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return currentReturnState.getOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean goToNext() {
|
||||||
|
if ( currentReturnState == null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( currentReturnState.indicatesMoreOutputs() )
|
||||||
// prepare the next return state
|
// prepare the next return state
|
||||||
try {
|
try {
|
||||||
final boolean isResultSet = jdbcStatement.getMoreResults();
|
final boolean isResultSet = jdbcStatement.getMoreResults();
|
||||||
currentReturnState = buildCurrentReturnDescriptor( isResultSet );
|
currentReturnState = buildCurrentReturnState( isResultSet );
|
||||||
}
|
}
|
||||||
catch (SQLException e) {
|
catch (SQLException e) {
|
||||||
throw convert( e, "Error calling CallableStatement.getMoreResults" );
|
throw convert( e, "Error calling CallableStatement.getMoreResults" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentReturnState != null && currentReturnState.indicatesMoreReturns();
|
// and return
|
||||||
|
return currentReturnState != null && currentReturnState.indicatesMoreOutputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Output getNextOutput() {
|
public void release() {
|
||||||
if ( !hasMoreOutput() ) {
|
try {
|
||||||
throw new NoMoreReturnsException( "Results have been exhausted" );
|
jdbcStatement.close();
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
log.debug( "Unable to close PreparedStatement", e );
|
||||||
}
|
}
|
||||||
|
|
||||||
return getCurrentOutput();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List extractCurrentResults() {
|
private List extractCurrentResults() {
|
||||||
|
@ -143,14 +156,6 @@ public class OutputsImpl implements Outputs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JDBCException convert(SQLException e, String message) {
|
|
||||||
return context.getSession().getFactory().getSQLExceptionHelper().convert(
|
|
||||||
e,
|
|
||||||
message,
|
|
||||||
context.getSql()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates the information needed to interpret the current return within a result
|
* Encapsulates the information needed to interpret the current return within a result
|
||||||
*/
|
*/
|
||||||
|
@ -165,7 +170,7 @@ public class OutputsImpl implements Outputs {
|
||||||
this.updateCount = updateCount;
|
this.updateCount = updateCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean indicatesMoreReturns() {
|
public boolean indicatesMoreOutputs() {
|
||||||
return isResultSet() || getUpdateCount() >= 0;
|
return isResultSet() || getUpdateCount() >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,14 +182,14 @@ public class OutputsImpl implements Outputs {
|
||||||
return updateCount;
|
return updateCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Output getReturn() {
|
public Output getOutput() {
|
||||||
if ( rtn == null ) {
|
if ( rtn == null ) {
|
||||||
rtn = buildReturn();
|
rtn = buildOutput();
|
||||||
}
|
}
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Output buildReturn() {
|
protected Output buildOutput() {
|
||||||
if ( log.isDebugEnabled() ) {
|
if ( log.isDebugEnabled() ) {
|
||||||
log.debugf(
|
log.debugf(
|
||||||
"Building Return [isResultSet=%s, updateCount=%s, extendedReturn=%s",
|
"Building Return [isResultSet=%s, updateCount=%s, extendedReturn=%s",
|
||||||
|
@ -204,10 +209,10 @@ public class OutputsImpl implements Outputs {
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( isResultSet() ) {
|
if ( isResultSet() ) {
|
||||||
return new ResultSetOutputImpl( extractCurrentResults() );
|
return buildResultSetOutput( extractCurrentResults() );
|
||||||
}
|
}
|
||||||
else if ( getUpdateCount() >= 0 ) {
|
else if ( getUpdateCount() >= 0 ) {
|
||||||
return new UpdateCountOutputImpl( updateCount );
|
return buildUpdateCountOutput( updateCount );
|
||||||
}
|
}
|
||||||
else if ( hasExtendedReturns() ) {
|
else if ( hasExtendedReturns() ) {
|
||||||
return buildExtendedReturn();
|
return buildExtendedReturn();
|
||||||
|
@ -218,6 +223,14 @@ public class OutputsImpl implements Outputs {
|
||||||
|
|
||||||
// hooks for stored procedure (out param) processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// hooks for stored procedure (out param) processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
protected Output buildResultSetOutput(List list) {
|
||||||
|
return new ResultSetOutputImpl( list );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Output buildUpdateCountOutput(int updateCount) {
|
||||||
|
return new UpdateCountOutputImpl( updateCount );
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean hasExtendedReturns() {
|
protected boolean hasExtendedReturns() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -227,53 +240,9 @@ public class OutputsImpl implements Outputs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class ResultSetOutputImpl implements ResultSetOutput {
|
|
||||||
private final List results;
|
|
||||||
|
|
||||||
public ResultSetOutputImpl(List results) {
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
this.results = results;
|
// Hooks into Hibernate's Loader hierarchy for ResultSet -> Object mapping
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isResultSet() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public List getResultList() {
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getSingleResult() {
|
|
||||||
final List results = getResultList();
|
|
||||||
if ( results == null || results.isEmpty() ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return results.get( 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class UpdateCountOutputImpl implements UpdateCountOutput {
|
|
||||||
private final int updateCount;
|
|
||||||
|
|
||||||
public UpdateCountOutputImpl(int updateCount) {
|
|
||||||
this.updateCount = updateCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getUpdateCount() {
|
|
||||||
return updateCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isResultSet() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static CustomLoaderExtension buildSpecializedCustomLoader(final ResultContext context) {
|
private static CustomLoaderExtension buildSpecializedCustomLoader(final ResultContext context) {
|
||||||
// might be better to just manually construct the Return(s).. SQLQueryReturnProcessor does a lot of
|
// might be better to just manually construct the Return(s).. SQLQueryReturnProcessor does a lot of
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.result.internal;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.result.ResultSetOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of ResultSetOutput
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
class ResultSetOutputImpl implements ResultSetOutput {
|
||||||
|
private final List results;
|
||||||
|
|
||||||
|
public ResultSetOutputImpl(List results) {
|
||||||
|
this.results = results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResultSet() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public List getResultList() {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getSingleResult() {
|
||||||
|
final List results = getResultList();
|
||||||
|
if ( results == null || results.isEmpty() ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return results.get( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.result.internal;
|
||||||
|
|
||||||
|
import org.hibernate.result.UpdateCountOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of UpdateCountOutput
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
class UpdateCountOutputImpl implements UpdateCountOutput {
|
||||||
|
private final int updateCount;
|
||||||
|
|
||||||
|
public UpdateCountOutputImpl(int updateCount) {
|
||||||
|
this.updateCount = updateCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUpdateCount() {
|
||||||
|
return updateCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResultSet() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -169,9 +169,9 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
||||||
Session session = openSession();
|
Session session = openSession();
|
||||||
session.beginTransaction();
|
session.beginTransaction();
|
||||||
|
|
||||||
ProcedureCall query = session.createStoredProcedureCall( "user");
|
ProcedureCall procedureCall = session.createStoredProcedureCall( "user");
|
||||||
ProcedureOutputs procedureResult = query.getResult();
|
ProcedureOutputs procedureOutputs = procedureCall.getResult();
|
||||||
Output currentOutput = procedureResult.getCurrentOutput();
|
Output currentOutput = procedureOutputs.getCurrent();
|
||||||
assertNotNull( currentOutput );
|
assertNotNull( currentOutput );
|
||||||
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
||||||
String name = (String) resultSetReturn.getSingleResult();
|
String name = (String) resultSetReturn.getSingleResult();
|
||||||
|
@ -188,7 +188,7 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
||||||
|
|
||||||
ProcedureCall query = session.createStoredProcedureCall( "findOneUser" );
|
ProcedureCall query = session.createStoredProcedureCall( "findOneUser" );
|
||||||
ProcedureOutputs procedureResult = query.getResult();
|
ProcedureOutputs procedureResult = query.getResult();
|
||||||
Output currentOutput = procedureResult.getCurrentOutput();
|
Output currentOutput = procedureResult.getCurrent();
|
||||||
assertNotNull( currentOutput );
|
assertNotNull( currentOutput );
|
||||||
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
||||||
Object result = resultSetReturn.getSingleResult();
|
Object result = resultSetReturn.getSingleResult();
|
||||||
|
@ -207,7 +207,7 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
||||||
|
|
||||||
ProcedureCall query = session.createStoredProcedureCall( "findUsers" );
|
ProcedureCall query = session.createStoredProcedureCall( "findUsers" );
|
||||||
ProcedureOutputs procedureResult = query.getResult();
|
ProcedureOutputs procedureResult = query.getResult();
|
||||||
Output currentOutput = procedureResult.getCurrentOutput();
|
Output currentOutput = procedureResult.getCurrent();
|
||||||
assertNotNull( currentOutput );
|
assertNotNull( currentOutput );
|
||||||
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
||||||
List results = resultSetReturn.getResultList();
|
List results = resultSetReturn.getResultList();
|
||||||
|
@ -244,7 +244,7 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
||||||
query.registerParameter( "start", Integer.class, ParameterMode.IN ).bindValue( 1 );
|
query.registerParameter( "start", Integer.class, ParameterMode.IN ).bindValue( 1 );
|
||||||
query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
|
query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
|
||||||
ProcedureOutputs procedureResult = query.getResult();
|
ProcedureOutputs procedureResult = query.getResult();
|
||||||
Output currentOutput = procedureResult.getCurrentOutput();
|
Output currentOutput = procedureResult.getCurrent();
|
||||||
assertNotNull( currentOutput );
|
assertNotNull( currentOutput );
|
||||||
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
||||||
List results = resultSetReturn.getResultList();
|
List results = resultSetReturn.getResultList();
|
||||||
|
@ -269,7 +269,7 @@ public class StoredProcedureTest extends BaseCoreFunctionalTestCase {
|
||||||
query.registerParameter( 1, Integer.class, ParameterMode.IN ).bindValue( 1 );
|
query.registerParameter( 1, Integer.class, ParameterMode.IN ).bindValue( 1 );
|
||||||
query.registerParameter( 2, Integer.class, ParameterMode.IN ).bindValue( 2 );
|
query.registerParameter( 2, Integer.class, ParameterMode.IN ).bindValue( 2 );
|
||||||
ProcedureOutputs procedureResult = query.getResult();
|
ProcedureOutputs procedureResult = query.getResult();
|
||||||
Output currentOutput = procedureResult.getCurrentOutput();
|
Output currentOutput = procedureResult.getCurrent();
|
||||||
assertNotNull( currentOutput );
|
assertNotNull( currentOutput );
|
||||||
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
|
||||||
List results = resultSetReturn.getResultList();
|
List results = resultSetReturn.getResultList();
|
||||||
|
|
|
@ -41,6 +41,8 @@ import java.util.List;
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.procedure.NoSuchParameterException;
|
||||||
|
import org.hibernate.procedure.ParameterStrategyException;
|
||||||
import org.hibernate.procedure.ProcedureCall;
|
import org.hibernate.procedure.ProcedureCall;
|
||||||
import org.hibernate.procedure.ProcedureCallMemento;
|
import org.hibernate.procedure.ProcedureCallMemento;
|
||||||
import org.hibernate.procedure.ProcedureOutputs;
|
import org.hibernate.procedure.ProcedureOutputs;
|
||||||
|
@ -199,27 +201,10 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
|
|
||||||
// outputs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// outputs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
private ProcedureOutputs outputs() {
|
|
||||||
if ( procedureResult == null ) {
|
|
||||||
procedureResult = procedureCall.getResult();
|
|
||||||
}
|
|
||||||
return procedureResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getOutputParameterValue(int position) {
|
|
||||||
return outputs().getOutputParameterValue( position );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getOutputParameterValue(String parameterName) {
|
|
||||||
return outputs().getOutputParameterValue( parameterName );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute() {
|
public boolean execute() {
|
||||||
try {
|
try {
|
||||||
final Output rtn = outputs().getCurrentOutput();
|
final Output rtn = outputs().getCurrent();
|
||||||
return rtn != null && ResultSetOutput.class.isInstance( rtn );
|
return rtn != null && ResultSetOutput.class.isInstance( rtn );
|
||||||
}
|
}
|
||||||
catch (NoMoreReturnsException e) {
|
catch (NoMoreReturnsException e) {
|
||||||
|
@ -227,23 +212,64 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ProcedureOutputs outputs() {
|
||||||
|
if ( procedureResult == null ) {
|
||||||
|
procedureResult = procedureCall.getResult();
|
||||||
|
}
|
||||||
|
return procedureResult;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int executeUpdate() {
|
public int executeUpdate() {
|
||||||
if ( ! entityManager().isTransactionInProgress() ) {
|
if ( ! entityManager().isTransactionInProgress() ) {
|
||||||
throw new TransactionRequiredException( "javax.persistence.Query.executeUpdate requires active transaction" );
|
throw new TransactionRequiredException( "javax.persistence.Query.executeUpdate requires active transaction" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the expectation is that there is just one Output, of type UpdateCountOutput
|
||||||
|
try {
|
||||||
|
execute();
|
||||||
return getUpdateCount();
|
return getUpdateCount();
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
outputs().release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getOutputParameterValue(int position) {
|
||||||
|
try {
|
||||||
|
return outputs().getOutputParameterValue( position );
|
||||||
|
}
|
||||||
|
catch (ParameterStrategyException e) {
|
||||||
|
throw new IllegalArgumentException( "Invalid mix of named and positional parameters", e );
|
||||||
|
}
|
||||||
|
catch (NoSuchParameterException e) {
|
||||||
|
throw new IllegalArgumentException( e.getMessage(), e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getOutputParameterValue(String parameterName) {
|
||||||
|
try {
|
||||||
|
return outputs().getOutputParameterValue( parameterName );
|
||||||
|
}
|
||||||
|
catch (ParameterStrategyException e) {
|
||||||
|
throw new IllegalArgumentException( "Invalid mix of named and positional parameters", e );
|
||||||
|
}
|
||||||
|
catch (NoSuchParameterException e) {
|
||||||
|
throw new IllegalArgumentException( e.getMessage(), e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasMoreResults() {
|
public boolean hasMoreResults() {
|
||||||
return outputs().hasMoreOutput() && ResultSetOutput.class.isInstance( outputs().getCurrentOutput() );
|
return outputs().goToNext() && ResultSetOutput.class.isInstance( outputs().getCurrent() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUpdateCount() {
|
public int getUpdateCount() {
|
||||||
try {
|
try {
|
||||||
final Output rtn = outputs().getCurrentOutput();
|
final Output rtn = outputs().getCurrent();
|
||||||
if ( rtn == null ) {
|
if ( rtn == null ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -262,9 +288,9 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
||||||
@Override
|
@Override
|
||||||
public List getResultList() {
|
public List getResultList() {
|
||||||
try {
|
try {
|
||||||
final Output rtn = outputs().getCurrentOutput();
|
final Output rtn = outputs().getCurrent();
|
||||||
if ( ! ResultSetOutput.class.isInstance( rtn ) ) {
|
if ( ! ResultSetOutput.class.isInstance( rtn ) ) {
|
||||||
throw new IllegalStateException( "Current CallableStatement return was not a ResultSet, but getResultList was called" );
|
throw new IllegalStateException( "Current CallableStatement ou was not a ResultSet, but getResultList was called" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( (ResultSetOutput) rtn ).getResultList();
|
return ( (ResultSetOutput) rtn ).getResultList();
|
||||||
|
|
|
@ -51,6 +51,8 @@ import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||||
import org.hibernate.jpa.internal.util.CacheModeHelper;
|
import org.hibernate.jpa.internal.util.CacheModeHelper;
|
||||||
import org.hibernate.jpa.internal.util.ConfigurationHelper;
|
import org.hibernate.jpa.internal.util.ConfigurationHelper;
|
||||||
import org.hibernate.jpa.internal.util.LockModeTypeHelper;
|
import org.hibernate.jpa.internal.util.LockModeTypeHelper;
|
||||||
|
import org.hibernate.procedure.NoSuchParameterException;
|
||||||
|
import org.hibernate.procedure.ParameterStrategyException;
|
||||||
|
|
||||||
import static org.hibernate.jpa.QueryHints.HINT_CACHEABLE;
|
import static org.hibernate.jpa.QueryHints.HINT_CACHEABLE;
|
||||||
import static org.hibernate.jpa.QueryHints.HINT_CACHE_MODE;
|
import static org.hibernate.jpa.QueryHints.HINT_CACHE_MODE;
|
||||||
|
@ -439,7 +441,8 @@ public abstract class BaseQueryImpl implements Query {
|
||||||
protected abstract boolean isJpaPositionalParameter(int position);
|
protected abstract boolean isJpaPositionalParameter(int position);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hibernate specific extension to the JPA {@link javax.persistence.Parameter} contract.
|
* Hibernate specific extension to the JPA {@link javax.persistence.Parameter} contract. Used here to track
|
||||||
|
* information known about the parameter.
|
||||||
*/
|
*/
|
||||||
protected static interface ParameterRegistration<T> extends Parameter<T> {
|
protected static interface ParameterRegistration<T> extends Parameter<T> {
|
||||||
/**
|
/**
|
||||||
|
@ -450,6 +453,12 @@ public abstract class BaseQueryImpl implements Query {
|
||||||
*/
|
*/
|
||||||
public ParameterMode getMode();
|
public ParameterMode getMode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can we bind (set) values on this parameter? Generally this is {@code true}, but would not be in the case
|
||||||
|
* of parameters with OUT or REF_CURSOR mode.
|
||||||
|
*
|
||||||
|
* @return Whether the parameter is bindable (can set be called).
|
||||||
|
*/
|
||||||
public boolean isBindable();
|
public boolean isBindable();
|
||||||
|
|
||||||
public void bindValue(T value);
|
public void bindValue(T value);
|
||||||
|
@ -459,6 +468,11 @@ public abstract class BaseQueryImpl implements Query {
|
||||||
public ParameterBind<T> getBind();
|
public ParameterBind<T> getBind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the value currently bound to a particular parameter.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
protected static interface ParameterBind<T> {
|
protected static interface ParameterBind<T> {
|
||||||
public T getValue();
|
public T getValue();
|
||||||
|
|
||||||
|
@ -648,6 +662,12 @@ public abstract class BaseQueryImpl implements Query {
|
||||||
try {
|
try {
|
||||||
findParameterRegistration( position ).bindValue( value, temporalType );
|
findParameterRegistration( position ).bindValue( value, temporalType );
|
||||||
}
|
}
|
||||||
|
catch (ParameterStrategyException e) {
|
||||||
|
throw new IllegalArgumentException( "Invalid mix of named and positional parameters", e );
|
||||||
|
}
|
||||||
|
catch (NoSuchParameterException e) {
|
||||||
|
throw new IllegalArgumentException( e.getMessage(), e );
|
||||||
|
}
|
||||||
catch (QueryParameterException e) {
|
catch (QueryParameterException e) {
|
||||||
throw new IllegalArgumentException( e );
|
throw new IllegalArgumentException( e );
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,9 @@ import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
|
||||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests various JPA usage scenarios for performing stored procedures. Inspired by the awesomely well-done JPA TCK
|
* Tests various JPA usage scenarios for performing stored procedures. Inspired by the awesomely well-done JPA TCK
|
||||||
|
@ -107,6 +109,42 @@ public class JpaTckUsageTest extends BaseUnitTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@FailureExpected( jiraKey = "HHH-8416", message = "JPA TCK challenge" )
|
||||||
|
public void testHasMoreResultsHandlingTckChallenge() {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = em.createStoredProcedureQuery( "findOneUser", User.class );
|
||||||
|
assertTrue( query.execute() );
|
||||||
|
assertTrue( query.hasMoreResults() );
|
||||||
|
query.getResultList();
|
||||||
|
assertFalse( query.hasMoreResults() );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHasMoreResultsHandling() {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = em.createStoredProcedureQuery( "findOneUser", User.class );
|
||||||
|
assertTrue( query.execute() );
|
||||||
|
query.getResultList();
|
||||||
|
assertFalse( query.hasMoreResults() );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResultClassHandling() {
|
public void testResultClassHandling() {
|
||||||
EntityManager em = entityManagerFactory.createEntityManager();
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
@ -148,6 +186,38 @@ public class JpaTckUsageTest extends BaseUnitTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSettingNonExistingParams() {
|
||||||
|
EntityManager em = entityManagerFactory.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// non-existing positional param
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = em.createNamedStoredProcedureQuery( "positional-param" );
|
||||||
|
query.setParameter( 99, 1 );
|
||||||
|
fail( "Expecting an exception" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException expected) {
|
||||||
|
// this is the expected condition
|
||||||
|
}
|
||||||
|
|
||||||
|
// non-existing named param
|
||||||
|
try {
|
||||||
|
StoredProcedureQuery query = em.createNamedStoredProcedureQuery( "positional-param" );
|
||||||
|
query.setParameter( "does-not-exist", 1 );
|
||||||
|
fail( "Expecting an exception" );
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException expected) {
|
||||||
|
// this is the expected condition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected( jiraKey = "HHH-8395", message = "Out of the frying pan into the fire: https://issues.apache.org/jira/browse/DERBY-211" )
|
@FailureExpected( jiraKey = "HHH-8395", message = "Out of the frying pan into the fire: https://issues.apache.org/jira/browse/DERBY-211" )
|
||||||
public void testExecuteUpdate() {
|
public void testExecuteUpdate() {
|
||||||
|
@ -167,6 +237,10 @@ public class JpaTckUsageTest extends BaseUnitTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testParameterRegistration() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// todo : look at ways to allow "Auxiliary DB Objects" to the db via EMF bootstrapping.
|
// todo : look at ways to allow "Auxiliary DB Objects" to the db via EMF bootstrapping.
|
||||||
|
|
||||||
// public static final String findOneUser_CREATE_CMD = "CREATE ALIAS findOneUser AS $$\n" +
|
// public static final String findOneUser_CREATE_CMD = "CREATE ALIAS findOneUser AS $$\n" +
|
||||||
|
@ -317,6 +391,13 @@ public class JpaTckUsageTest extends BaseUnitTestCase {
|
||||||
conn.close();
|
conn.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void findUserIds(ResultSet[] results) throws SQLException {
|
||||||
|
Connection conn = DriverManager.getConnection( "jdbc:default:connection" );
|
||||||
|
PreparedStatement ps = conn.prepareStatement( "select id from t_user" );
|
||||||
|
results[0] = ps.executeQuery();
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
|
||||||
public static void deleteAllUsers() throws SQLException {
|
public static void deleteAllUsers() throws SQLException {
|
||||||
// afaict the only way to return update counts here is to actually perform some DML
|
// afaict the only way to return update counts here is to actually perform some DML
|
||||||
Connection conn = DriverManager.getConnection( "jdbc:default:connection" );
|
Connection conn = DriverManager.getConnection( "jdbc:default:connection" );
|
||||||
|
|
Loading…
Reference in New Issue