-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 
Author Message
 Post subject: calling Hibernate Stored Procedures - help needed
PostPosted: Fri Jan 19, 2007 11:11 am 
Newbie

Joined: Thu Dec 14, 2006 12:23 pm
Posts: 6
Hey there. We are trying to re-write an application using Hibernate/Spring/JSF. This is a legacy app where a majority of the logic resides inside of the database as stored procedures. As part of our application, we have a stored procedure that does some logging, system maintainance, and puts a row into a table. This stored procedure doesn't return a value. From reading the documentation, it's pretty clear that when calling a stored procedure you need to have the first variable in a stored procedure be an OUT variable. I wrote a wrapper function around the stored procedure to return a sys_refcursor (via the hibernate docs). I am just assuming that the error that is getting thrown below is because I don't have a return value mapped.

When I was trying to call the original stored procedure without a return value I was getting what appeared to be 'off by one' errors (I would have two variables, would call setParameter(0,"a") and setParameter(1,"foo") and would receive the error "cannot set parameter:3").

My question is how do I map this return value? It's essentially a dummy value just to get this to work.. it doesn't map to a table or any type in our system. I've been haggling with this for two days now and don't see a concrete example of how to use it.

Thanks in advance!



Hibernate version:
3.2.0

Mapping documents:
Code:
<hibernate-mapping> 

  <sql-query name="send_message"  callable="true">
 
   { call web_send_message(:entityId, :text, :deviceId) } 
  </sql-query>
 
    <sql-query  name="send_message_only"  callable="true">
   { call medctr.op_send_message(:entityId, 'MEDICAL', :text, 'F', NULL, 'F', 'F', NULL, 'F', '1', 'F', 'F', 'F', :deviceId, 'F', NULL) }
  </sql-query>

</hibernate-mapping>



Code between sessionFactory.openSession() and session.close():
Code:
getNamedQuery("send_message");   

         LOG.error("we are setting text");
          query.setString("text", "this is a test page");
                   LOG.error("we are setting entityId");
         query.setString("entityId", "6389")
             .setString("deviceId", null)
         /*LOG.error("we are setting pagerID");
          query.setParameter("deviceId","123456")*/
             .list();
         
      }
      catch (Exception e) {
         LOG.error("we threw an exception",e);
      }



Full stack trace of any exception that occurs:
Code:
2007-01-19 08:52:15,894 DEBUG [org.hibernate.jdbc.AbstractBatcher] - <about to open PreparedStatement (open PreparedStatements: 0, globally: 0)>
2007-01-19 08:52:15,894 DEBUG [org.hibernate.jdbc.ConnectionManager] - <opening JDBC connection>
2007-01-19 08:52:15,941 DEBUG [org.hibernate.SQL] - <{ call web_send_message(?, ?, ?) }>
2007-01-19 08:52:15,941 DEBUG [org.hibernate.jdbc.AbstractBatcher] - <preparing statement>
2007-01-19 08:52:16,223 DEBUG [org.hibernate.loader.Loader] - <bindNamedParameters() this is a test page -> text [3]>
2007-01-19 08:52:16,223 DEBUG [org.hibernate.type.StringType] - <binding 'this is a test page' to parameter: 3>
2007-01-19 08:52:16,223 DEBUG [org.hibernate.loader.Loader] - <bindNamedParameters() null -> deviceId [4]>
2007-01-19 08:52:16,223 DEBUG [org.hibernate.type.StringType] - <binding null to parameter: 4>
2007-01-19 08:52:16,238 INFO [org.hibernate.type.StringType] - <could not bind value 'null' to parameter: 4; Invalid column index>



Name and version of the database you are using:
Oracle 10G


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 12:02 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
if you don't need the return value then why don't you either

a) use .executeUpdate()

or

b) just use a normal jdbc connection to do the call ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 12:44 pm 
Newbie

Joined: Thu Dec 14, 2006 12:23 pm
Posts: 6
The short answer is because I am new to hibernate.

Thanks a million!! After a little tinkering, that worked!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 25, 2007 10:56 am 
Beginner
Beginner

Joined: Mon Mar 07, 2005 6:23 pm
Posts: 21
max wrote:
if you don't need the return value then why don't you either

a) use .executeUpdate()

or

b) just use a normal jdbc connection to do the call ?


Hate to perform thread necromancy here, but doesn't .executeUpdate() throw a

Exception in thread "main" java.lang.IllegalArgumentException: callable not yet supported for native queries

in this situation?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 25, 2007 11:57 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
not if you use an uptodate version of hibernate

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 18, 2007 10:20 am 
Newbie

Joined: Wed Oct 04, 2006 5:14 am
Posts: 1
max wrote:
not if you use an uptodate version of hibernate

What is the uptodate version You're referring to?

In 3.2.5.ga source NativeSQLQueryPlan
Code:
   public int performExecuteUpdate(QueryParameters queryParameters,
         SessionImplementor session) throws HibernateException {
      
      coordinateSharedCacheCleanup( session );
      
      if(queryParameters.isCallable()) {
         throw new IllegalArgumentException("callable not yet supported for native queries");
      }
...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 18, 2007 11:38 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
I stand corrected - it only works for call syntax on dbs that allow it for prepared statemetns.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 18, 2007 11:57 am 
Beginner
Beginner

Joined: Wed May 16, 2007 7:12 am
Posts: 41
Location: London
Code:
CallableStatement st = hibernateSession
                    .connection()
                    .prepareCall(
                            "{? = call abc(?)}");

            st.registerOutParameter(0, java.sql.Types.INTEGER);
            st.set(1, 123));
st.execute();
st.getInt(1);



I believe that is how I got the result for a record count query. If the oracle function is returning a resultset. Use code as below.

Code:
st.registerOutParameter(i++, OracleTypes.CURSOR);
st.execute();
ResultSet rs = (ResultSet) st.getObject(1);


then you can use the resultset as you please.

Cheers!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 18, 2007 12:03 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
yup - that is the hack we use to support callable for oracle.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 18, 2007 12:22 pm 
Newbie

Joined: Fri Dec 07, 2007 2:24 pm
Posts: 7
Location: Columbia, MD
Since you are using Spring, have you consider using the StoredProcedure Wrapper that Spring provides?

http://static.springframework.org/sprin ... edure.html

I've used it before and was pretty straight forward.

_________________
Alberto
http://www.linkedin.com/in/aflores


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 18, 2007 12:34 pm 
Beginner
Beginner

Joined: Wed May 16, 2007 7:12 am
Posts: 41
Location: London
aflores wrote:
Since you are using Spring, have you consider using the StoredProcedure Wrapper that Spring provides?

http://static.springframework.org/sprin ... edure.html

I've used it before and was pretty straight forward.


Do you think you could post a simple example please?

_________________
Dinesh Mahadevan

Visit me at http://www.yelani.com/


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 18, 2007 1:02 pm 
Newbie

Joined: Fri Dec 07, 2007 2:24 pm
Posts: 7
Location: Columbia, MD
Quote:
Do you think you could post a simple example please?


Well, first this would be a Spring answer (I apologize in advanced).

Most of the code I wrote is proprietary information, however most of what I wrote is found at Spring documentation (which has a pretty decent information). They also have a good forum where you can search for Stored Procedures.

http://static.springframework.org/sprin ... dProcedure

You should end up with something like (this is code and pseudocode).

public MyStoredProcedure extends StoredProcedure {
public Bar(JdbcTemplate template, String name) {
super(template, name);
}

// more code as you need it ...
}

public FooDao extends JdbcTemplate {

public Object executeStoreProcedureOne(String value1, ...) {

MyStoredProcedure sp = new MyStoredProcedure(getJdbcTemplate(), "<name_of_your_sp>");

// follow the Stored Procedure API
// Map allParameters = new .... (build parameters)
// sp.declareParameters
// sp.execute(allParameters);
}
}

Needless to say that if you use this approach, you need to make this JdbcTemplate take part of your transaction manager (which you may or may not be familiar with). Spring forums can help you a lot more with this (this is hardly a Hibernate question).

_________________
Alberto
http://www.linkedin.com/in/aflores


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 24, 2008 7:31 pm 
Newbie

Joined: Thu Jan 24, 2008 6:30 pm
Posts: 3
I have a problem with this code let me see:

private void listaInfoUser(String arg1){
Session session;
session = sessionFactory.openSession();
CallableStatement st;
try {
st = session.connection().prepareCall("{? = call selectTestInfoUser_sp(?)}");
st.registerOutParameter(1, java.sql.Types.VARCHAR);
st.setString(1, arg1);
st.execute();

} catch (HibernateException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}

and the error display:

java.sql.SQLException: Falta el parámetro IN o OUT en el índice:: 2
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:1844)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3311)
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3422)
at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4394)
at mx.uam.hibernate.ManejadorUser.listaInfoUser(ManejadorUser.java:38)
at mx.uam.hibernate.ManejadorUser.main(ManejadorUser.java:50)

What´s happen?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.