-->
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.  [ 10 posts ] 
Author Message
 Post subject: Cannot get Hibernate to check results of stored procedures
PostPosted: Fri Aug 27, 2010 1:58 pm 
Newbie

Joined: Sun Apr 18, 2010 11:56 pm
Posts: 5
I've read the documentation, and even have some working code with Hibernate, MySQL, and calling stored procedures for sql-insert, sql-delete, and somewhat for sql-update. But it wasn't easy because much of the documentation seems inaccurate, and incomplete - at least when using MySQL.

I have written several stored procedures that I have tested and are working for inserting, updating and deleting tables using mysql, and I can even get Hibernate to call the stored procedure, but I cannot seem to get Hibernate to recognize the returned result which indicates the success(or failure) of the procedure.

I've tried several approaches, and none seem to work:
1) Making the first parameter of the stored procedure an OUT parameter and setting it to ROW_COUNT(),
The error in this case is that JDBC reports an exception that the number of parameters passed to the procedure is N-1. After investigating, Hibernate is not providing a parameter for the OUT parameter, it is only supplying the parameters corresponding to columns defined in the mapping.

2) Changed the procedure to only have the provided IN parameters (removed the first OUT parameter). Now it is returning the ROW_COUNT() as the last statement of the procedure - and it works correctly when tested on Query Browser.
Hibernate reports an exception after (successful) completion of the stored procedure:
Exception: StaleStateException
Message: Batch update returned unexpected row count from update [0]; actual row count: -1; expected: 1
In Class: org.hibernate.jdbc.Expectations$BasicExpectation
In Method: checkBatched() : Expectations.java : 85
The problem here is that Hibernate is somehow not checking the result-set returned, because it is definitely returning a 1.

So does anyone know how to get this to work?

I am using mySQL 5.1.3, and Hibernate 3.3.2


Top
 Profile  
 
 Post subject: Re: Cannot get Hibernate to check results of stored procedures
PostPosted: Wed Sep 01, 2010 8:42 pm 
Newbie

Joined: Sun Apr 18, 2010 11:56 pm
Posts: 5
For INSERT (sql-insert) and DELETE (sql-delete), I have temporarily used the workaround of check="none". For UPDATE (sql-update) I eventually found a workaround using check="rowcount". (I could not accept check="none".)

I think there are two problems here:

1) I cannot seem to get Hibernate to issue the the parameter needed for the OUT parameter approach for mysql. Has anyone been able to get this to work?

2) Hibernate is not looking for a returned resultset. It is somehow referring to the mysql ROW_COUNT() function return for sql-update. If *any* intervening statements are executed in the procedure after the UPDATE but before exiting the procedure, the ROW_COUNT() function may not return the correct value.

This latter observation seems unfortunate, since stored procedures may frequently need to do other work in addition to the actual update (or insert, delete).

Is there some way to get Hibernate to actually look at the returned resultset instead directly looking at the value returned by the ROW_COUNT() function ?


Top
 Profile  
 
 Post subject: Re: Cannot get Hibernate to check results of stored procedures
PostPosted: Tue Sep 28, 2010 12:37 pm 
Regular
Regular

Joined: Thu Oct 19, 2006 12:07 pm
Posts: 75
I'm having similar problems.

Is there a working example of using stored procedures (or functions - PostgreSQL) for sql-insert and co?

Is check="none" the only workable solution?

I did basically this:
- in hbm:
Code:
<sql-insert callable="true">{call mydb.createMyEntity (?, ?, ?, ?, ?, ?, ?, ?)}</sql-insert>

Parameters are the same as in hibernates own SQL.

The function (DB is PostgreSQL 8.4) is:
Code:

CREATE OR REPLACE FUNCTION mydb.createMyEntity(
  a_name character varying(50),
  a_address character varying(200),
  a_city character varying(100),
  a_post_code character varying(10),
  a_country_code character varying(3),
  a_foo character varying(200),
  a_bar_fk_id integer,
  a_my_id integer
)   RETURNS void AS $$
BEGIN

INSERT INTO mydb.my_table VALUES ($8,  $7,  $1 ,  $2 ,  $3,  $4 ,  $5,  $6 );

END;
$$ LANGUAGE plpgsql;


When I try to persist an object, I get this exception/log:
Code:
Hibernate: {call mydb.createMyEntity (?, ?, ?, ?, ?, ?, ?, ?)}
18:35:05.343 [main] ERROR org.hibernate.jdbc.AbstractBatcher - Exception executing batch:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1


Should there be more in the stored function?
The stored function is called. I checked by putting RAISE EXCEPTION statements in it.

Regards,
David


Top
 Profile  
 
 Post subject: Re: Cannot get Hibernate to check results of stored procedures
PostPosted: Sat Nov 27, 2010 2:43 am 
Newbie

Joined: Fri Nov 26, 2010 7:21 am
Posts: 4
Did both of you get the solution?

i'm having the same problem, calling stored function for 'select' is working fine but for insert, update, and delete i'm getting StaleStateException


Top
 Profile  
 
 Post subject: Re: Cannot get Hibernate to check results of stored procedures
PostPosted: Sat Nov 27, 2010 8:05 am 
Regular
Regular

Joined: Thu Oct 19, 2006 12:07 pm
Posts: 75
I managed to make it work for all cases.
I think I just used check="none" (I am not at my development machine right now, I will check on monday).


Top
 Profile  
 
 Post subject: Re: Cannot get Hibernate to check results of stored procedures
PostPosted: Mon Nov 29, 2010 1:31 am 
Newbie

Joined: Fri Nov 26, 2010 7:21 am
Posts: 4
then how to set the updated values on pojo, i called the stored function for update through getNamedQuery().

the question may be silly, but i'm new to hibernate..
any help will be appreciated


regards,
prabha


Top
 Profile  
 
 Post subject: Re: Cannot get Hibernate to check results of stored procedures
PostPosted: Tue Nov 30, 2010 2:27 pm 
Regular
Regular

Joined: Thu Oct 19, 2006 12:07 pm
Posts: 75
OK, I found it:
Note, this is for PostgreSQL database!

Code:
<class> ... (normal definition of id, properties and relations ...)

<loader query-ref="loadShopSP"/> <!-- see below for definition -->

         <!-- add check="none" as workaround for failure
            see http://opensource.atlassian.com/projects/hibernate/browse/HHH-1792 -->
      <sql-insert  check="none" callable="true">{call createShopHB (?, ?, ?, ?, ?, ?, ?)}</sql-insert>
      <sql-update check="none" callable="true">{call updateShopHB(?, ?, ?, ?, ?, ?, ?)}</sql-update>
      <sql-delete check="none" callable="true">{call deleteShopHB(?)}</sql-delete>
   </class>

<!-- load Shop by custom SQL instead of automatic hibernate generated code -->
<!-- this is not a stored procedure, but I left it here ... -->
<sql-query name="loadShop">
    <return alias="shop" class="entity.Shop" lock-mode="upgrade"/>
    SELECT
      NAME AS {shop.name},
      ID AS {shop.id},
      address AS {shop.address},
      city AS {shop.city},
      post_code AS {shop.postCode},
      country_code AS {shop.countryCode},
      working_hours AS {shop.workingHours}
    FROM shop
    WHERE ID=?
    FOR UPDATE
</sql-query>

<!-- try loading Shop by using a stored procedure -->
   <sql-query name="loadShopSP" > <!-- callable="true"  does not work   -->
      <return alias="shop" class="entity.Shop">
         <return-property name="employee" column="EMPLOYEE" />
         <return-property name="id" column="id" />
         <return-property name="name" column="name" />
         <return-property name="address" column="address" />
         <return-property name="city" column="city" />
         <return-property name="postCode" column="post_code" />
         <return-property name="countryCode" column="country_code" />
         <return-property name="workingHours" column="working_hours" />
      </return>
      <!--{? = call loadShopHB(?)} this way does not work -->
      select * from loadShopHB(?)
   </sql-query>

<!-- custom query that returns a list of Shop objects  -->
   <sql-query name="selectAllShops" > <!-- callable="true"  does not work   -->
      <return alias="shop" class="entity.Shop">
         <return-property name="id" column="id" />
         <return-property name="name" column="name" />
         <return-property name="address" column="address" />
         <return-property name="city" column="city" />
         <return-property name="postCode" column="post_code" />
         <return-property name="countryCode" column="country_code" />
         <return-property name="workingHours" column="working_hours" />
      </return>
      <!-- {? = call getAllShopsHB()}  this way does not work -->
      select * from getAllShopsHB()
   </sql-query>



And here are the stored procedures:

Code:

CREATE OR REPLACE FUNCTION createShopHB(
  a_name character varying(50),
  a_address character varying(200),
  a_city character varying(100),
  a_post_code character varying(10),
  a_country_code character varying(3),
  a_working_hours character varying(200),
  a_id integer
) RETURNS void  AS $$

BEGIN

INSERT INTO shop VALUES (
  a_id,
  a_name ,
  a_address ,
  a_city ,
  a_post_code ,
  a_country_code ,
  a_working_hours )
;

END;
$$ LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION updateShopHB(
  a_name character varying(50),
  a_address character varying(200),
  a_city character varying(100),
  a_post_code character varying(10),
  a_country_code character varying(3),
  a_working_hours character varying(200),
  a_id integer
) RETURNS void  AS $$

BEGIN

  update shop set
    name=a_name, address=a_address, city=a_city, post_code=a_post_code,
    country_code=a_country_code, working_hours=a_working_hours
  where id=a_id;

END;
$$ LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION deleteShopHB(
  a_id integer
) RETURNS void  AS $$

BEGIN

  delete from shop where id=a_id;

END;
$$ LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION loadShopHB(
  a_id integer
) RETURNS SETOF shop  AS $$

BEGIN
RETURN QUERY SELECT *
    FROM shop
    WHERE
      id = a_id;
END;
$$ LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION getAllShopsHB()
  RETURNS SETOF shop  AS $$

BEGIN
RETURN QUERY SELECT *
    FROM shop;
END;
$$ LANGUAGE plpgsql;



Top
 Profile  
 
 Post subject: Re: Cannot get Hibernate to check results of stored procedures
PostPosted: Wed Dec 01, 2010 3:19 am 
Newbie

Joined: Fri Nov 26, 2010 7:21 am
Posts: 4
Hi xerces8,

how do you call createShopHB (?, ?, ?, ?, ?, ?, ?) instead of callable statement in hibernate dao


Top
 Profile  
 
 Post subject: Re: Cannot get Hibernate to check results of stored procedures
PostPosted: Wed Dec 01, 2010 11:10 am 
Regular
Regular

Joined: Thu Oct 19, 2006 12:07 pm
Posts: 75
I just use session.save(someStore) and that uses the SQL procedure defined in cfg.


Top
 Profile  
 
 Post subject: Re: Cannot get Hibernate to check results of stored procedures
PostPosted: Wed Dec 01, 2010 11:16 am 
Regular
Regular

Joined: Thu Oct 19, 2006 12:07 pm
Posts: 75
And here some examples of calling SQL directly from Java code:

Code:
Boolean result = (Boolean) session.
    createSQLQuery("select hasUserRight(:param1, :param2)").
    setParameter("param1", userId).
    setParameter("param2", rightId).
    uniqueResult();

////////////

Store result = (Store) session
    .createSQLQuery("select* from loadStoreHB(:param1)").
    addEntity(Store.class).
    setParameter("param1", id).
    uniqueResult();

////////

List<Store> result = (List<Store>) session.
    createSQLQuery("select * from getAllStoresHB()").
    addEntity(Store.class).
    list();



The stored procedure:

Code:

CREATE OR REPLACE FUNCTION hasUserRight(a_user_id int, a_right_id int) RETURNS boolean
AS $$
DECLARE
    quantity integer;
BEGIN

SELECT count(*) INTO quantity
FROM xxxxxx //details deleted//
WHERE
  user_id = a_user_id
   AND  right_id = a_right_id
;

RETURN quantity > 0;

END;
$$ LANGUAGE plpgsql


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 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.