HHH-8411 - StoredProcedureQuery : getResultList and hasMoreResults() mot implemented properly
This commit is contained in:
parent
f4cc86f7ad
commit
f99e1e4b4a
|
@ -72,36 +72,6 @@ public class ProcedureResultImpl extends ResultImpl implements ProcedureResult {
|
|||
return new ProcedureCurrentReturnState( isResultSet, updateCount, refCursorParamIndex );
|
||||
}
|
||||
|
||||
protected boolean hasMoreReturns(CurrentReturnState descriptor) {
|
||||
return super.hasMoreReturns( descriptor )
|
||||
|| ( (ProcedureCurrentReturnState) descriptor ).refCursorParamIndex < refCursorParameters.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasExtendedReturns(CurrentReturnState currentReturnState) {
|
||||
return ProcedureCurrentReturnState.class.isInstance( currentReturnState )
|
||||
&& ( (ProcedureCurrentReturnState) currentReturnState ).refCursorParamIndex < refCursorParameters.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Return buildExtendedReturn(CurrentReturnState returnDescriptor) {
|
||||
this.refCursorParamIndex++;
|
||||
final int refCursorParamIndex = ( (ProcedureCurrentReturnState) returnDescriptor ).refCursorParamIndex;
|
||||
final ParameterRegistrationImplementor refCursorParam = refCursorParameters[refCursorParamIndex];
|
||||
ResultSet resultSet;
|
||||
if ( refCursorParam.getName() != null ) {
|
||||
resultSet = procedureCall.getSession().getFactory().getServiceRegistry()
|
||||
.getService( RefCursorSupport.class )
|
||||
.getResultSet( callableStatement, refCursorParam.getName() );
|
||||
}
|
||||
else {
|
||||
resultSet = procedureCall.getSession().getFactory().getServiceRegistry()
|
||||
.getService( RefCursorSupport.class )
|
||||
.getResultSet( callableStatement, refCursorParam.getPosition() );
|
||||
}
|
||||
return new ResultSetReturnImpl( extractResults( resultSet ) );
|
||||
}
|
||||
|
||||
protected class ProcedureCurrentReturnState extends CurrentReturnState {
|
||||
private final int refCursorParamIndex;
|
||||
|
||||
|
@ -109,6 +79,35 @@ public class ProcedureResultImpl extends ResultImpl implements ProcedureResult {
|
|||
super( isResultSet, updateCount );
|
||||
this.refCursorParamIndex = refCursorParamIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean indicatesMoreReturns() {
|
||||
return super.indicatesMoreReturns()
|
||||
|| ProcedureResultImpl.this.refCursorParamIndex < ProcedureResultImpl.this.refCursorParameters.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasExtendedReturns() {
|
||||
return refCursorParamIndex < refCursorParameters.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Return buildExtendedReturn() {
|
||||
ProcedureResultImpl.this.refCursorParamIndex++;
|
||||
final ParameterRegistrationImplementor refCursorParam = ProcedureResultImpl.this.refCursorParameters[refCursorParamIndex];
|
||||
ResultSet resultSet;
|
||||
if ( refCursorParam.getName() != null ) {
|
||||
resultSet = ProcedureResultImpl.this.procedureCall.getSession().getFactory().getServiceRegistry()
|
||||
.getService( RefCursorSupport.class )
|
||||
.getResultSet( ProcedureResultImpl.this.callableStatement, refCursorParam.getName() );
|
||||
}
|
||||
else {
|
||||
resultSet = ProcedureResultImpl.this.procedureCall.getSession().getFactory().getServiceRegistry()
|
||||
.getService( RefCursorSupport.class )
|
||||
.getResultSet( ProcedureResultImpl.this.callableStatement, refCursorParam.getPosition() );
|
||||
}
|
||||
return new ResultSetReturnImpl( extractResults( resultSet ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -113,11 +113,7 @@ public class ResultImpl implements Result {
|
|||
throw convert( e, "Error calling CallableStatement.getMoreResults" );
|
||||
}
|
||||
|
||||
return hasMoreReturns( currentReturnState );
|
||||
}
|
||||
|
||||
protected boolean hasMoreReturns(CurrentReturnState descriptor) {
|
||||
return descriptor != null && ( descriptor.isResultSet() || descriptor.getUpdateCount() >= 0 );
|
||||
return currentReturnState != null && currentReturnState.indicatesMoreReturns();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -129,10 +125,6 @@ public class ResultImpl implements Result {
|
|||
return getCurrentReturn();
|
||||
}
|
||||
|
||||
protected boolean hasExtendedReturns(CurrentReturnState currentReturnState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private List extractCurrentResults() {
|
||||
try {
|
||||
return extractResults( jdbcStatement.getResultSet() );
|
||||
|
@ -151,10 +143,6 @@ public class ResultImpl implements Result {
|
|||
}
|
||||
}
|
||||
|
||||
protected Return buildExtendedReturn(CurrentReturnState copyReturnDescriptor) {
|
||||
throw new NoMoreReturnsException();
|
||||
}
|
||||
|
||||
protected JDBCException convert(SQLException e, String message) {
|
||||
return context.getSession().getFactory().getSQLExceptionHelper().convert(
|
||||
e,
|
||||
|
@ -177,6 +165,10 @@ public class ResultImpl implements Result {
|
|||
this.updateCount = updateCount;
|
||||
}
|
||||
|
||||
public boolean indicatesMoreReturns() {
|
||||
return isResultSet() || getUpdateCount() >= 0;
|
||||
}
|
||||
|
||||
public boolean isResultSet() {
|
||||
return isResultSet;
|
||||
}
|
||||
|
@ -198,9 +190,18 @@ public class ResultImpl implements Result {
|
|||
"Building Return [isResultSet=%s, updateCount=%s, extendedReturn=%s",
|
||||
isResultSet(),
|
||||
getUpdateCount(),
|
||||
hasExtendedReturns( currentReturnState )
|
||||
hasExtendedReturns()
|
||||
);
|
||||
}
|
||||
// todo : temporary for tck testing...
|
||||
System.out.println(
|
||||
String.format(
|
||||
"Building Return [isResultSet=%s, updateCount=%s, extendedReturn=%s",
|
||||
isResultSet(),
|
||||
getUpdateCount(),
|
||||
hasExtendedReturns()
|
||||
)
|
||||
);
|
||||
|
||||
if ( isResultSet() ) {
|
||||
return new ResultSetReturnImpl( extractCurrentResults() );
|
||||
|
@ -208,12 +209,22 @@ public class ResultImpl implements Result {
|
|||
else if ( getUpdateCount() >= 0 ) {
|
||||
return new UpdateCountReturnImpl( updateCount );
|
||||
}
|
||||
else if ( hasExtendedReturns( currentReturnState ) ) {
|
||||
return buildExtendedReturn( currentReturnState );
|
||||
else if ( hasExtendedReturns() ) {
|
||||
return buildExtendedReturn();
|
||||
}
|
||||
|
||||
throw new NoMoreReturnsException();
|
||||
}
|
||||
|
||||
// hooks for stored procedure (out param) processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
protected boolean hasExtendedReturns() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Return buildExtendedReturn() {
|
||||
throw new IllegalStateException( "State does not define extended returns" );
|
||||
}
|
||||
}
|
||||
|
||||
protected static class ResultSetReturnImpl implements ResultSetReturn {
|
||||
|
|
|
@ -33,6 +33,7 @@ import javax.persistence.PersistenceException;
|
|||
import javax.persistence.Query;
|
||||
import javax.persistence.StoredProcedureQuery;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
@ -44,6 +45,7 @@ import org.hibernate.procedure.ParameterRegistration;
|
|||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.procedure.ProcedureCallMemento;
|
||||
import org.hibernate.procedure.ProcedureResult;
|
||||
import org.hibernate.result.NoMoreReturnsException;
|
||||
import org.hibernate.result.ResultSetReturn;
|
||||
import org.hibernate.result.Return;
|
||||
import org.hibernate.result.UpdateCountReturn;
|
||||
|
@ -217,46 +219,63 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
|
||||
@Override
|
||||
public boolean execute() {
|
||||
final Return rtn = outputs().getCurrentReturn();
|
||||
return rtn != null && ResultSetReturn.class.isInstance( rtn );
|
||||
try {
|
||||
final Return rtn = outputs().getCurrentReturn();
|
||||
return rtn != null && ResultSetReturn.class.isInstance( rtn );
|
||||
}
|
||||
catch (NoMoreReturnsException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate() {
|
||||
if ( ! entityManager().isTransactionInProgress() ) {
|
||||
throw new TransactionRequiredException( "javax.persistence.Query.executeUpdate requires active transaction" );
|
||||
}
|
||||
return getUpdateCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMoreResults() {
|
||||
return outputs().hasMoreReturns();
|
||||
return outputs().hasMoreReturns() && ResultSetReturn.class.isInstance( outputs().getCurrentReturn() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUpdateCount() {
|
||||
final Return rtn = outputs().getCurrentReturn();
|
||||
if ( rtn == null ) {
|
||||
return -1;
|
||||
try {
|
||||
final Return rtn = outputs().getCurrentReturn();
|
||||
if ( rtn == null ) {
|
||||
return -1;
|
||||
}
|
||||
else if ( UpdateCountReturn.class.isInstance( rtn ) ) {
|
||||
return ( (UpdateCountReturn) rtn ).getUpdateCount();
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if ( UpdateCountReturn.class.isInstance( rtn ) ) {
|
||||
return ( (UpdateCountReturn) rtn ).getUpdateCount();
|
||||
}
|
||||
else {
|
||||
catch (NoMoreReturnsException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List getResultList() {
|
||||
final Return rtn = outputs().getCurrentReturn();
|
||||
if ( ! ResultSetReturn.class.isInstance( rtn ) ) {
|
||||
throw new IllegalStateException( "Current CallableStatement was not a ResultSet, but getResultList was called" );
|
||||
}
|
||||
try {
|
||||
final Return rtn = outputs().getCurrentReturn();
|
||||
if ( ! ResultSetReturn.class.isInstance( rtn ) ) {
|
||||
throw new IllegalStateException( "Current CallableStatement return was not a ResultSet, but getResultList was called" );
|
||||
}
|
||||
|
||||
if ( outputs().hasMoreReturns() ) {
|
||||
outputs().getNextReturn();
|
||||
return ( (ResultSetReturn) rtn ).getResultList();
|
||||
}
|
||||
catch (NoMoreReturnsException e) {
|
||||
// todo : the spec is completely silent on these type of edge-case scenarios.
|
||||
// Essentially here we'd have a case where there are no more results (ResultSets nor updateCount) but
|
||||
// getResultList was called.
|
||||
return null;
|
||||
}
|
||||
|
||||
return ( (ResultSetReturn) rtn ).getResultList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -305,17 +324,14 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
// ugh ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public Query setLockMode(LockModeType lockMode) {
|
||||
return null;
|
||||
throw new IllegalStateException( "javax.persistence.Query.setLockMode not valid on javax.persistence.StoredProcedureQuery" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockModeType getLockMode() {
|
||||
return null;
|
||||
throw new IllegalStateException( "javax.persistence.Query.getLockMode not valid on javax.persistence.StoredProcedureQuery" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -755,16 +755,20 @@ public abstract class BaseQueryImpl implements Query {
|
|||
checkOpen( false );
|
||||
|
||||
final ParameterRegistration<T> registration = findParameterRegistration( param );
|
||||
if ( registration != null ) {
|
||||
if ( ! registration.isBindable() ) {
|
||||
throw new IllegalArgumentException( "Passed parameter [" + param + "] is not bindable" );
|
||||
}
|
||||
final ParameterBind<T> bind = registration.getBind();
|
||||
if ( bind != null ) {
|
||||
return bind.getValue();
|
||||
}
|
||||
if ( registration == null ) {
|
||||
throw new IllegalArgumentException( "Passed parameter [" + param + "] is not a (registered) parameter of this query" );
|
||||
}
|
||||
throw new IllegalStateException( "Parameter [" + param + "] has not yet been bound" );
|
||||
|
||||
if ( ! registration.isBindable() ) {
|
||||
throw new IllegalStateException( "Passed parameter [" + param + "] is not bindable" );
|
||||
}
|
||||
|
||||
final ParameterBind<T> bind = registration.getBind();
|
||||
if ( bind == null ) {
|
||||
throw new IllegalStateException( "Parameter [" + param + "] has not yet been bound" );
|
||||
}
|
||||
|
||||
return bind.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue