@Test public void calculate() { log.info("... calculate ..."); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // define the stored procedure StoredProcedureQuery query = em.createStoredProcedureQuery("calculate"); query.registerStoredProcedureParameter("x", Double.class, ParameterMode.IN); query.registerStoredProcedureParameter("y", Double.class, ParameterMode.IN); query.registerStoredProcedureParameter("sum", Double.class, ParameterMode.OUT); // set input parameter query.setParameter("x", 1.23d); query.setParameter("y", 4d); // call the stored procedure and get the result query.execute(); Double sum = (Double) query.getOutputParameterValue("sum"); log.info("Calculation result: 1.23 + 4 = " + sum); em.getTransaction().commit(); em.close(); }
@Test public void testHibernateProcedureCallRefCursor() { doInJPA(entityManager -> { Session session = entityManager.unwrap(Session.class); ProcedureCall call = session .createStoredProcedureCall("post_comments"); call.registerParameter(1, void.class, ParameterMode.REF_CURSOR); call.registerParameter(2, Long.class, ParameterMode.IN).bindValue(1L); Output output = call.getOutputs().getCurrent(); if (output.isResultSet()) { List<Object[]> postComments = ((ResultSetOutput) output).getResultList(); assertEquals(2, postComments.size()); } }); }
private AbstractParameterRegistrationImpl( ProcedureCallImpl procedureCall, Integer position, String name, ParameterMode mode, Class<T> type, Type hibernateType) { this.procedureCall = procedureCall; this.position = position; this.name = name; this.mode = mode; this.type = type; if ( mode == ParameterMode.REF_CURSOR ) { return; } setHibernateType( hibernateType ); }
@Override @SuppressWarnings("unchecked") public T extract(CallableStatement statement) { if ( mode == ParameterMode.IN ) { throw new ParameterMisuseException( "IN parameter not valid for output extraction" ); } else if ( mode == ParameterMode.REF_CURSOR ) { throw new ParameterMisuseException( "REF_CURSOR parameters should be accessed via results" ); } try { if ( ProcedureParameterExtractionAware.class.isInstance( hibernateType ) ) { return (T) ( (ProcedureParameterExtractionAware) hibernateType ).extract( statement, startIndex, session() ); } else { return (T) statement.getObject( startIndex ); } } catch (SQLException e) { throw procedureCall.getSession().getFactory().getSQLExceptionHelper().convert( e, "Unable to extract OUT/INOUT parameter value" ); } }
/** * Creates a Backup of the Database in the directory specified in * config.properties. * * @param name the name of the Backup. * * @return Backup entinty. * * @throws QueryTimeoutException if the query should fail. * @throws PersistenceException if persisting should fail. * @Throws IOException if config.properties is not readable. */ public Backup runBackup(String name) throws QueryTimeoutException, PersistenceException, IOException { Properties props = ServerProperties.getProperties(); Date date = new Date(); String path = props.getProperty(dirPropertyKey) + name + "_" + getDateAsString(date); StoredProcedureQuery query = em.createStoredProcedureQuery( "SYSCS_UTIL.SYSCS_BACKUP_DATABASE"); query.registerStoredProcedureParameter(1, String.class, ParameterMode.IN); query.setParameter(1, path); query.execute(); log.debug("Backup query executed!"); Backup backup = generateBackup(name, path, date, getDirectorySize(new File(path))); return backup; }
@Test public void testHibernateProcedureCallMultipleOutParameter() { doInJPA(entityManager -> { StoredProcedureQuery query = entityManager .createStoredProcedureQuery("getStatistics") .registerStoredProcedureParameter( "A", Long.class, ParameterMode.OUT) .registerStoredProcedureParameter( "B", Long.class, ParameterMode.OUT) .registerStoredProcedureParameter( "C", Long.class, ParameterMode.OUT); query.execute(); Long a = (Long) query .getOutputParameterValue("A"); Long b = (Long) query .getOutputParameterValue("B"); Long c = (Long) query .getOutputParameterValue("C"); }); }
@Test public void testStoredProcedureRefCursor() { try { doInJPA(entityManager -> { StoredProcedureQuery query = entityManager.createStoredProcedureQuery("post_comments"); query.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN); query.registerStoredProcedureParameter(2, Class.class, ParameterMode.REF_CURSOR); query.setParameter(1, 1L); query.execute(); List<Object[]> postComments = query.getResultList(); assertNotNull(postComments); }); } catch (Exception e) { assertTrue(Pattern.compile("Dialect .*? not known to support REF_CURSOR parameters").matcher(e.getCause().getMessage()).matches()); } }
@Test public void testFunction() { try { doInJPA(entityManager -> { StoredProcedureQuery query = entityManager.createStoredProcedureQuery("fn_count_comments"); query.registerStoredProcedureParameter("postId", Long.class, ParameterMode.IN); query.setParameter("postId", 1L); Long commentCount = (Long) query.getSingleResult(); assertEquals(Long.valueOf(2), commentCount); }); } catch (Exception e) { assertTrue(Pattern.compile("PROCEDURE high_performance_java_persistence.fn_count_comments does not exist").matcher(e.getCause().getCause().getMessage()).matches()); } }
@Test public void testStoredProcedureOutParameter() { doInJPA(entityManager -> { StoredProcedureQuery query = entityManager .createStoredProcedureQuery("count_comments") .registerStoredProcedureParameter( "postId", Long.class, ParameterMode.IN) .registerStoredProcedureParameter( "commentCount", Long.class, ParameterMode.OUT) .setParameter("postId", 1L); query.execute(); Long commentCount = (Long) query.getOutputParameterValue("commentCount"); assertEquals(Long.valueOf(2), commentCount); }); }
@Test public void testStoredProcedureRefCursor() { try { doInJPA(entityManager -> { StoredProcedureQuery query = entityManager .createStoredProcedureQuery("post_comments") .registerStoredProcedureParameter(1, Long.class, ParameterMode.IN) .registerStoredProcedureParameter(2, Class.class, ParameterMode.REF_CURSOR) .setParameter(1, 1L); query.execute(); List<Object[]> postComments = query.getResultList(); assertNotNull(postComments); }); } catch (Exception e) { assertTrue(Pattern.compile("Dialect .*? not known to support REF_CURSOR parameters").matcher(e.getCause().getMessage()).matches()); } }
@Test public void shouldInvokeStoredProcedureWithOutbound() throws Exception { utx.begin(); StoredProcedureQuery query = em.createStoredProcedureQuery("DOUBLE_SP") .registerStoredProcedureParameter( "P1", Float.class, ParameterMode.IN) .registerStoredProcedureParameter( "P2", Float.class, ParameterMode.OUT) .setParameter("P1", new Float(2.345)); boolean status = query.execute(); System.out.printf("****************** status=%s\n", status); assertFalse( query.hasMoreResults()); Double p2 = ( Double)query.getOutputParameterValue("P2"); System.out.printf("The output P2 was %12.7f\n", p2 ); utx.commit(); }
@Test public void shouldInvokeStoredProcedureWithOutbound() throws Exception { StoredProcedureQuery query = em.createStoredProcedureQuery("COMPOUND_INTEREST_SP") .registerStoredProcedureParameter( "P", Float.class, ParameterMode.IN) .registerStoredProcedureParameter( "r", Float.class, ParameterMode.IN) .registerStoredProcedureParameter( "n", Integer.class, ParameterMode.IN) .registerStoredProcedureParameter( "t", Integer.class, ParameterMode.IN) .registerStoredProcedureParameter( "A", Float.class, ParameterMode.OUT) .setParameter("P", new Float(1500)) .setParameter("r", new Float(0.043)) .setParameter("n", new Integer(4)) .setParameter("t", new Integer(6)); // P = 1500, r = 0.043 (4.3%), n = 4, and t = 6: boolean status = query.execute(); System.out.printf("****************** status=%s\n", status); assertFalse( query.hasMoreResults()); Double A = ( Double)query.getOutputParameterValue("A"); System.out.printf("The output A was %12.7f\n", A ); assertEquals( 1938.84, A, 0.005 ); }
@Test public void shouldInvokeStoredProcedureWithResultSet() throws Exception { utx.begin(); StoredProcedureQuery query = em.createStoredProcedureQuery("READ_TAX_SP") .registerStoredProcedureParameter( "TAX_CODE_ID", Integer.class, ParameterMode.IN) .setParameter("TAX_CODE_ID", 101); boolean status = query.execute(); System.out.printf("****************** status=%s\n", status); List rs = query.getResultList(); assertNotNull(rs); System.out.printf("****************** rs=%s\n", rs ); Object row[] = (Object[])rs.get(0); System.out.printf("****************** row=%s\n", row ); for (int col=0; col<row.length; ++col ) { System.out.printf("**** row[%d]=%s\n", col, row[col] ); } utx.commit(); }
@Test public void plainJpa21() { StoredProcedureQuery proc = em.createStoredProcedureQuery("plus1inout"); proc.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN); proc.registerStoredProcedureParameter(2, Integer.class, ParameterMode.OUT); proc.setParameter(1, 1); proc.execute(); assertThat(proc.getOutputParameterValue(2), is((Object) 2)); }
@Override public void registerParameters( String procedureName, CallableStatement statement, ParameterStrategy parameterStrategy, List<ParameterRegistrationImplementor<?>> parameterRegistrations, SessionImplementor session) { // prepare parameters int i = 1; try { for ( ParameterRegistrationImplementor parameter : parameterRegistrations ) { if ( parameter.getMode() == ParameterMode.REF_CURSOR ) { statement.registerOutParameter( i, Types.OTHER ); i++; } else { parameter.prepare( statement, i ); i += parameter.getSqlTypes().length; } } } catch (SQLException e) { throw session.getFactory().getSQLExceptionHelper().convert( e, "Error registering CallableStatement parameters", procedureName ); } }
@Override public String renderCallableStatement( String procedureName, ParameterStrategy parameterStrategy, List<ParameterRegistrationImplementor<?>> parameterRegistrations, SessionImplementor session) { final StringBuilder buffer = new StringBuilder().append( "{call " ) .append( procedureName ) .append( "(" ); String sep = ""; for ( ParameterRegistrationImplementor parameter : parameterRegistrations ) { if ( parameter == null ) { throw new QueryException( "Parameter registrations had gaps" ); } if ( parameter.getMode() == ParameterMode.REF_CURSOR ) { verifyRefCursorSupport( session.getFactory().getDialect() ); buffer.append( sep ).append( "?" ); sep = ","; } else { for ( int i = 0; i < parameter.getSqlTypes().length; i++ ) { buffer.append( sep ).append( "?" ); sep = ","; } } } return buffer.append( ")}" ).toString(); }
@Override public void registerParameters( String procedureName, CallableStatement statement, ParameterStrategy parameterStrategy, List<ParameterRegistrationImplementor<?>> parameterRegistrations, SessionImplementor session) { // prepare parameters int i = 1; try { for ( ParameterRegistrationImplementor parameter : parameterRegistrations ) { parameter.prepare( statement, i ); if ( parameter.getMode() == ParameterMode.REF_CURSOR ) { i++; } else { i += parameter.getSqlTypes().length; } } } catch (SQLException e) { throw session.getFactory().getSQLExceptionHelper().convert( e, "Error registering CallableStatement parameters", procedureName ); } }
@Override @SuppressWarnings("unchecked") public <T> ParameterRegistration<T> registerParameter(int position, Class<T> type, ParameterMode mode) { final PositionalParameterRegistration parameterRegistration = new PositionalParameterRegistration( this, position, mode, type ); registerParameter( parameterRegistration ); return parameterRegistration; }
@Override @SuppressWarnings("unchecked") public <T> ParameterRegistration<T> registerParameter(String name, Class<T> type, ParameterMode mode) { final NamedParameterRegistration parameterRegistration = new NamedParameterRegistration( this, name, mode, type ); registerParameter( parameterRegistration ); return parameterRegistration; }
/** * Collects any parameter registrations which indicate a REF_CURSOR parameter type/mode. * * @return The collected REF_CURSOR type parameters. */ public ParameterRegistrationImplementor[] collectRefCursorParameters() { final List<ParameterRegistrationImplementor> refCursorParams = new ArrayList<ParameterRegistrationImplementor>(); for ( ParameterRegistrationImplementor param : registeredParameters ) { if ( param.getMode() == ParameterMode.REF_CURSOR ) { refCursorParams.add( param ); } } return refCursorParams.toArray( new ParameterRegistrationImplementor[refCursorParams.size()] ); }
NamedParameterRegistration( ProcedureCallImpl procedureCall, String name, ParameterMode mode, Class<T> type) { super( procedureCall, name, mode, type ); }
NamedParameterRegistration( ProcedureCallImpl procedureCall, String name, ParameterMode mode, Class<T> type, Type hibernateType) { super( procedureCall, name, mode, type, hibernateType ); }
protected AbstractParameterRegistrationImpl( ProcedureCallImpl procedureCall, Integer position, ParameterMode mode, Class<T> type) { this( procedureCall, position, null, mode, type ); }
protected AbstractParameterRegistrationImpl( ProcedureCallImpl procedureCall, Integer position, ParameterMode mode, Class<T> type, Type hibernateType) { this( procedureCall, position, null, mode, type, hibernateType ); }
protected AbstractParameterRegistrationImpl( ProcedureCallImpl procedureCall, String name, ParameterMode mode, Class<T> type) { this( procedureCall, null, name, mode, type ); }
protected AbstractParameterRegistrationImpl( ProcedureCallImpl procedureCall, String name, ParameterMode mode, Class<T> type, Type hibernateType) { this( procedureCall, null, name, mode, type, hibernateType ); }
private AbstractParameterRegistrationImpl( ProcedureCallImpl procedureCall, Integer position, String name, ParameterMode mode, Class<T> type) { this( procedureCall, position, name, mode, type, procedureCall.getSession().getFactory().getTypeResolver().heuristicType( type.getName() ) ); }
public int[] getSqlTypes() { if ( mode == ParameterMode.REF_CURSOR ) { // we could use the Types#REF_CURSOR added in Java 8, but that would require requiring Java 8... throw new IllegalStateException( "REF_CURSOR parameters do not have a SQL/JDBC type" ); } return sqlTypes; }
PositionalParameterRegistration( ProcedureCallImpl procedureCall, Integer position, ParameterMode mode, Class<T> type) { super( procedureCall, position, mode, type ); }
PositionalParameterRegistration( ProcedureCallImpl procedureCall, Integer position, ParameterMode mode, Class<T> type, Type hibernateType) { super( procedureCall, position, mode, type, hibernateType ); }
/** * Saves a bid to the database * @param bid - bid */ public void save(Bid bid) { entityManager.persist(bid); StoredProcedureQuery spq = entityManager.createStoredProcedureQuery("getQtyOrders"); spq.registerStoredProcedureParameter("param1", Integer.class, ParameterMode.IN); spq.setParameter("param1",55); Object[] count = (Object[])spq.getSingleResult(); logger.log(Level.INFO, "Single result: {0}", count[0]); }
@Test public void testStoredProcedureOutParameter() { doInJPA(entityManager -> { StoredProcedureQuery query = entityManager.createStoredProcedureQuery("count_comments"); query.registerStoredProcedureParameter("postId", Long.class, ParameterMode.IN); query.registerStoredProcedureParameter("commentCount", Long.class, ParameterMode.OUT); query.setParameter("postId", 1L); query.execute(); Long commentCount = (Long) query.getOutputParameterValue("commentCount"); assertEquals(Long.valueOf(2), commentCount); }); }
@Test public void testHibernateProcedureCallOutParameter() { doInJPA(entityManager -> { Session session = entityManager.unwrap(Session.class); ProcedureCall call = session.createStoredProcedureCall("getStatistics"); call.registerParameter("postId", Long.class, ParameterMode.IN).bindValue(1L); call.registerParameter("commentCount", Long.class, ParameterMode.OUT); Long commentCount = (Long) call.getOutputs().getOutputParameterValue("commentCount"); assertEquals(Long.valueOf(2), commentCount); }); }
@Test public void testStoredProcedureReturnValue() { doInJPA(entityManager -> { StoredProcedureQuery query = entityManager.createStoredProcedureQuery("post_comments"); query.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN); query.setParameter(1, 1L); List<Object[]> postComments = query.getResultList(); assertEquals(2, postComments.size()); }); }
@Test public void testHibernateProcedureCallReturnValueParameter() { doInJPA(entityManager -> { Session session = entityManager.unwrap(Session.class); ProcedureCall call = session.createStoredProcedureCall("post_comments"); call.registerParameter(1, Long.class, ParameterMode.IN).bindValue(1L); Output output = call.getOutputs().getCurrent(); if (output.isResultSet()) { List<Object[]> postComments = ((ResultSetOutput) output).getResultList(); assertEquals(2, postComments.size()); } }); }
@Test public void testStoredProcedureOutParameter() { doInJPA(entityManager -> { StoredProcedureQuery query = entityManager .createStoredProcedureQuery("count_comments") .registerStoredProcedureParameter("postId", Long.class, ParameterMode.IN) .registerStoredProcedureParameter("commentCount", Long.class, ParameterMode.OUT) .setParameter("postId", 1L); query.execute(); Long commentCount = (Long) query.getOutputParameterValue("commentCount"); assertEquals(Long.valueOf(2), commentCount); }); }
@Test public void testStoredProcedureRefCursor() { doInJPA(entityManager -> { StoredProcedureQuery query = entityManager .createStoredProcedureQuery("post_comments") .registerStoredProcedureParameter(1, void.class, ParameterMode.REF_CURSOR) .registerStoredProcedureParameter(2, Long.class, ParameterMode.IN) .setParameter(2, 1L); List<Object[]> postComments = query.getResultList(); assertEquals(2, postComments.size()); }); }
@Override public String renderCallableStatement( String procedureName, ParameterStrategy parameterStrategy, List<ParameterRegistrationImplementor<?>> parameterRegistrations, SessionImplementor session) { // if there are any parameters, see if the first is REF_CURSOR final boolean firstParamIsRefCursor = ! parameterRegistrations.isEmpty() && parameterRegistrations.get( 0 ).getMode() == ParameterMode.REF_CURSOR; if ( firstParamIsRefCursor ) { // validate that the parameter strategy is positional (cannot mix, and REF_CURSOR is inherently positional) if ( parameterStrategy == ParameterStrategy.NAMED ) { throw new HibernateException( "Cannot mix named parameters and REF_CURSOR parameter on PostgreSQL" ); } } final StringBuilder buffer; if ( firstParamIsRefCursor ) { buffer = new StringBuilder().append( "{? = call " ); } else { buffer = new StringBuilder().append( "{call " ); } buffer.append( procedureName ).append( "(" ); String sep = ""; // skip the first registration if it was a REF_CURSOR final int startIndex = firstParamIsRefCursor ? 1 : 0; for ( int i = startIndex; i < parameterRegistrations.size(); i++ ) { final ParameterRegistrationImplementor parameter = parameterRegistrations.get( i ); // any additional REF_CURSOR parameter registrations are an error if ( parameter.getMode() == ParameterMode.REF_CURSOR ) { throw new HibernateException( "PostgreSQL supports only one REF_CURSOR parameter, but multiple were registered" ); } for ( int ignored : parameter.getSqlTypes() ) { buffer.append( sep ).append( "?" ); sep = ","; } } return buffer.append( ")}" ).toString(); }
@Override @SuppressWarnings("unchecked") public ProcedureCall registerParameter0(int position, Class type, ParameterMode mode) { registerParameter( position, type, mode ); return this; }
@Override @SuppressWarnings("unchecked") public ProcedureCall registerParameter0(String name, Class type, ParameterMode mode) { registerParameter( name, type, mode ); return this; }