How can we call a stored procedure using Hibernate or JPA?
Call a Stored Procedure Using the CreateNativeSQL Method. Hibernate allows to express queries in native SQL format directly. Therefore, we can straightforwardly create a native SQL query, and use the CALL statement to call the getAllFoos() stored procedure: Query query = session.
For a stored procedure which uses a SYS_REFCURSOR OUT parameter: CREATE OR REPLACE PROCEDURE post_comments ( postId IN NUMBER, postComments OUT SYS_REFCURSOR ) AS BEGIN OPEN postComments FOR SELECT * FROM post_comment WHERE post_id = postId; END; You can call it as follows: StoredProcedureQuery query = entityManager .
A stored procedure is a group of predefined SQL statements stored in the database. In Java, there are several ways to access stored procedures. In this tutorial, we'll learn how to call stored procedures from Spring Data JPA Repositories.
Considering the following stored procedure that simply returns a basic return value:
CREATE OR REPLACE PROCEDURE count_comments ( postId IN NUMBER, commentCount OUT NUMBER ) AS BEGIN SELECT COUNT(*) INTO commentCount FROM post_comment WHERE post_id = postId; END;
You can call this one with standard JPA:
StoredProcedureQuery query = entityManager .createStoredProcedureQuery("count_comments") .registerStoredProcedureParameter(1, Long.class, ParameterMode.IN) .registerStoredProcedureParameter(2, Long.class, ParameterMode.OUT) .setParameter(1, 1L); query.execute(); Long commentCount = (Long) query.getOutputParameterValue(2);
If the stored procedure returns a SYS_REFCURSOR:
CREATE OR REPLACE PROCEDURE post_comments ( postId IN NUMBER, postComments OUT SYS_REFCURSOR ) AS BEGIN OPEN postComments FOR SELECT * FROM post_comment WHERE post_id = postId; END;
You can call it like this:
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();
If you want to call an Oracle database function:
CREATE OR REPLACE FUNCTION fn_count_comments ( postId IN NUMBER ) RETURN NUMBER IS commentCount NUMBER; BEGIN SELECT COUNT(*) INTO commentCount FROM post_comment WHERE post_id = postId; RETURN( commentCount ); END;
You can't use the StoredProcedureQuery
since it does not work with Hibernate 5, so you can call it like this:
BigDecimal commentCount = (BigDecimal) entityManager .createNativeQuery( "SELECT fn_count_comments(:postId) FROM DUAL" ) .setParameter("postId", 1L) .getSingleResult();
or with plain JDBC:
Session session = entityManager.unwrap( Session.class ); Integer commentCount = session.doReturningWork( connection -> { try (CallableStatement function = connection.prepareCall( "{ ? = call fn_count_comments(?) }" )) { function.registerOutParameter( 1, Types.INTEGER ); function.setInt( 2, 1 ); function.execute(); return function.getInt( 1 ); } } );
For more details check out the following articles:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With