-->
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.  [ 8 posts ] 
Author Message
 Post subject: Hibernate and Sybase Anywhere specifications compliance
PostPosted: Thu Dec 01, 2005 9:52 am 
Newbie

Joined: Thu Dec 01, 2005 8:42 am
Posts: 7
Location: Paris
Hi !

I'm using Sybase Adaptive Server Anywhere (ASA) 9.0.2 with Hibernate 2.1.4 or 3.0. When i try to use native or identity id generators, on a very simple mapping, when I insert a row in the database, I always get an error from ASA :
SQL Error: -807, SQLState: HY000
[Sybase][ODBC Driver][Adaptive Server Anywhere]Host variables may not be used within a batch.
Indeed, when I look at the query generated by Hibernate, it performs in a batch :
1 - The query to insert the new row in database.
2 - the query to retrieve the last id generated : "select @@identity"
But the use of a host variable (@@identity) in a batch seems to violate ASA specifications.

Note that if I use "increment" for the id generator all is working perfectly. But this solution is to restrictive since only Hibernate can insert into the table.

My question is :
Do you know any solution to this problem ?
May I had a bug in JIRA, about this problem ?

See the informations below for more details.

Hibernate version:2.1.4 and 3.0
Using Sybase Anywhere Dialect :
org.hibernate.dialect.SybaseAnywhereDialect

Mapping documents:
The problem occur with a very simple mapping :
<class name="Customer" table="CUSTOMER" lazy="true">
<id name="id" column="ID" unsaved-value="null" type="integer">
<generator class="identity"/>
</id>
<property name="nom" column="NAME" type="string"/>
</class>

The table :
CREATE TABLE CUSTOMER (
ID INTEGER IDENTITY,
NAME VARCHAR(50) NOT NULL,
PRIMARY KEY (ID)
)


Code between sessionFactory.openSession() and session.close():
My Hibernate sessions are managed in a Filter. When the filter execute its body, I create a new Customer object (customer) and set its name.
Then i call : The save(Object obj) method on the session giving the Customer in parameter.
When the query is executed I get the following error.


Full stack trace of any exception that occurs:
Logs :
Code:
14:21:16,436  WARN JDBCExceptionReporter:71 - SQL Error: -807, SQLState: HY000
14:21:16,436 ERROR JDBCExceptionReporter:72 - [Sybase][ODBC Driver][Adaptive Server Anywhere]Host variables may not be used within a batch.


Stack :
Code:
org.hibernate.exception.GenericJDBCException: could not insert: [eTech.Customer]
   at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:82)
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:70)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1777)
   at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2178)
   at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:34)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:240)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:160)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:95)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)
   at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)
   at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
   at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)
   at org.hibernate.impl.SessionImpl.save(SessionImpl.java:481)
   at org.hibernate.impl.SessionImpl.save(SessionImpl.java:476)
   at i2.application.agendassgm.dao.DAO.save(DAO.java:56)
   at i2.application.agendassgm.facades.AdminFacade.creerPersonnelMedical(AdminFacade.java:485)
   at i2.application.agendassgm.facades.AdminFacade.creerMedecin(AdminFacade.java:448)
   at i2.application.agendassgm.ihm.action.PersonnelMedicalAction.confirmerAjoutPersonnelMedical(PersonnelMedicalAction.java:75)
   at i2.application.agendassgm.ihm.action.PersonnelMedicalAction.execute(PersonnelMedicalAction.java:42)
   at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
   at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
   at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
   at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
   at i2.application.agendassgm.filtre.TransactionEtAuthentificationFilter.doFilter(TransactionEtAuthentificationFilter.java:156)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
   at i2.application.agendassgm.filtre.TransactionEtAuthentificationFilter.doFilter(TransactionEtAuthentificationFilter.java:156)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
   at i2.application.cerbere.filtre.FiltreCerbere.doFilter(Unknown Source)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
   at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
   at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
   at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
   at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
   at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
   at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
   at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
   at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
   at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
   at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
   at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
   at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
   at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
   at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
   at java.lang.Thread.run(Thread.java:534)
Caused by: java.sql.SQLException: [Sybase][ODBC Driver][Adaptive Server Anywhere]Les variables hôte ne peuvent pas être utilisées dans un batch
   at ianywhere.ml.jdbcodbc.IPreparedStatement.execute(Native Method)
   at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:168)
   at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1744)
   ... 57 more


Name and version of the database you are using:
Adaptive Server Anywhere 9.0.2.3044

The generated SQL (show_sql=true):
Code:
insert into CUSTOMER (NAME) values (?)
select @@identity


Debug level Hibernate log excerpt:
[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 01, 2005 12:03 pm 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
hibernate.jdbc.batch_size = 0


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 01, 2005 12:27 pm 
Newbie

Joined: Thu Dec 01, 2005 8:42 am
Posts: 7
Location: Paris
I already try this tip.
The error stack, I paste in my original post, has been generated with hibernate.jdbc.batch_size = 0 !!!!

Thanks for your response.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 01, 2005 1:25 pm 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
If this setting doe's not help then submit bug report (it must dissable batch).


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 01, 2005 2:02 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
And it does, please don't submit a bogus bug report.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 5:37 am 
Newbie

Joined: Thu Dec 01, 2005 8:42 am
Posts: 7
Location: Paris
Indeed, It seems that the batch updates are disabled. But I notice in the logs generated by Hibernate that the sqlIdentityInsertString in BasicEntityPersister class is set to :
Code:
10:30:46,748 DEBUG BasicEntityPersister:2230 -  Identity insert: insert into CUSTOMER (NAME) values (?)\nselect @@identity


In other words, despite of the setting hibernate.jdbc.batch_size is set to 0, on insert events, two queries are issued. Adaptive Server Anywhere may consider this as a batch query, one of them using host variable "@@identity". This is typically what it doesn't like.

Thanks to both of you for taking time to answer my problem.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 7:18 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
What happens if you add this to SybaseAnywhereDialect:

Code:
   public boolean supportsInsertSelectIdentity() {
      return false;
   }


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 7:53 am 
Newbie

Joined: Thu Dec 01, 2005 8:42 am
Posts: 7
Location: Paris
Hi Gavin,

I try your suggestion and now it's working !!!
Hibernate performs two separated queries to the database :
- one with the insert,
- one with the "select @@identity"
And the insertion succeeds without any protest from ASA.

Do you consider this as a bug ?
Do I need to create one ?

Anyway, thank you for your solution.

Phylex.


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