@Override
  public Object getSingleResult() {
    final List resultList = getResultList();
    if (resultList == null || resultList.isEmpty()) {
      throw new NoResultException(
          String.format(
              "Call to stored procedure [%s] returned no results",
              procedureCall.getProcedureName()));
    } else if (resultList.size() > 1) {
      throw new NonUniqueResultException(
          String.format(
              "Call to stored procedure [%s] returned multiple results",
              procedureCall.getProcedureName()));
    }

    return resultList.get(0);
  }
  @Test
  public void testHibernateProcedureCallRefCursor() {
    doInJPA(
        this::entityManagerFactory,
        entityManager -> {
          // tag::sql-hibernate-call-sp-ref-cursor-oracle-example[]
          Session session = entityManager.unwrap(Session.class);

          ProcedureCall call = session.createStoredProcedureCall("personPhones");
          call.registerParameter(1, Long.class, ParameterMode.IN).bindValue(1L);
          call.registerParameter(2, Class.class, ParameterMode.REF_CURSOR);

          Output output = call.getOutputs().getCurrent();
          List<Object[]> postComments = ((ResultSetOutput) output).getResultList();
          assertEquals(2, postComments.size());
          // end::sql-hibernate-call-sp-ref-cursor-oracle-example[]
        });
  }
 /**
  * This form is used to build a StoredProcedureQueryImpl from a memento (usually from a
  * NamedStoredProcedureQuery).
  *
  * @param memento The memento
  * @param entityManager The EntityManager
  */
 @SuppressWarnings("unchecked")
 public StoredProcedureQueryImpl(
     ProcedureCallMemento memento, HibernateEntityManagerImplementor entityManager) {
   super(entityManager);
   this.procedureCall = memento.makeProcedureCall(entityManager.getSession());
   for (org.hibernate.procedure.ParameterRegistration nativeParamReg :
       procedureCall.getRegisteredParameters()) {
     registerParameter(new ParameterRegistrationImpl(this, nativeParamReg));
   }
 }
  @Override
  @SuppressWarnings("unchecked")
  public StoredProcedureQuery registerStoredProcedureParameter(
      String parameterName, Class type, ParameterMode mode) {
    entityManager().checkOpen(true);

    try {
      registerParameter(
          new ParameterRegistrationImpl(
              this, procedureCall.registerParameter(parameterName, type, mode)));
    } catch (HibernateException he) {
      throw entityManager().convert(he);
    } catch (RuntimeException e) {
      entityManager().markForRollbackOnly();
      throw e;
    }

    return this;
  }
 @Override
 protected boolean applyCacheRegionHint(String regionName) {
   procedureCall.setCacheRegion(regionName);
   return true;
 }
 @Override
 protected boolean applyCacheableHint(boolean isCacheable) {
   procedureCall.setCacheable(isCacheable);
   return true;
 }
 @Override
 protected boolean applyTimeoutHint(int timeout) {
   procedureCall.setTimeout(timeout);
   return true;
 }
 protected ProcedureOutputs outputs() {
   if (procedureResult == null) {
     procedureResult = procedureCall.getOutputs();
   }
   return procedureResult;
 }
 @Override
 protected boolean applyFlushModeHint(FlushMode flushMode) {
   procedureCall.setFlushMode(flushMode);
   return true;
 }
 @Override
 protected boolean applyCacheModeHint(CacheMode cacheMode) {
   procedureCall.setCacheMode(cacheMode);
   return true;
 }
 @Override
 protected boolean applyReadOnlyHint(boolean isReadOnly) {
   procedureCall.setReadOnly(isReadOnly);
   return true;
 }
 private void addNamedStoredProcedureQuery(String name, StoredProcedureQueryImpl query) {
   final ProcedureCall procedureCall = query.getHibernateProcedureCall();
   sessionFactory
       .getNamedQueryRepository()
       .registerNamedProcedureCallMemento(name, procedureCall.extractMemento(query.getHints()));
 }