-->
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.  [ 6 posts ] 
Author Message
 Post subject: Auto_Incremt Filed index incremented even sessionrolled back
PostPosted: Fri Jun 27, 2008 8:45 am 
Newbie

Joined: Fri Jun 27, 2008 8:16 am
Posts: 2
Hi All.

I am Newbie to Hibernate.
I have a table with primary key as autogenerate column. I am using Mysql 5.0.
I have given my mapping hbm file below.I am opening hibernate session.
I that session, I am inserting some data into this table. and after that I am insertintg into some other tables also in that same session.

What's my problem is when ever there is an error while inserting aonther table apart from my main table, session is getting rolled back without inserting data, But the auto increment field index is getting increased. So when ever there is a successful insert after some errors, my auto increment field value is jumping because of the errors incremented the index of that auto increment field.

Any body please help me to resolve this issue. How to roll back a session even with out incrementing auto generate index values.




Hibernate version: 3.0

Mapping documents:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.model.Ssagrtransactions" table="ssagrtransactions" >
<id name="lcno" type="java.lang.Long">
<column name="lcno" />
<generator class="identity" />
</id>
<property name="productId" type="java.lang.String">
<column name="Productid" length="20" not-null="true" />
</property>
<property name="batch" type="java.lang.String">
<column name="Batch" length="20" not-null="true" />
</property>
<property name="expDate" type="java.lang.Long">
<column name="Expdate" not-null="true" />
</property>
<property name="mfgDate" type="java.lang.Long">
<column name="Mfgdate" />
</property>
<property name="stnqty" type="java.lang.Float">
<column name="Stnqty" precision="12" scale="0" />
</property>
<property name="freeQty" type="java.lang.Float">
<column name="Freeqty" precision="12" scale="0" />
</property>
<property name="mrp" type="java.lang.Double">
<column name="mrp" precision="15" />
</property>
<property name="rate" type="java.lang.Double">
<column name="Rate" precision="15" not-null="true" />
</property>
<property name="ptr" type="java.lang.Double">
<column name="ptr" precision="15" />
</property>
<property name="vat" type="java.lang.Double">
<column name="vat" precision="15" />
</property>
<property name="amount" type="java.lang.Double">
<column name="Amount" precision="15" />
</property>
<property name="inDate" type="java.lang.Long">
<column name="Indate" />
</property>
<property name="invoiceNumber" type="java.lang.String">
<column name="Invoicenumber" length="20" not-null="true" />
</property>
<property name="invoiceDate" type="java.lang.Long">
<column name="Invoicedate" />
</property>
<property name="grnid" type="java.lang.String">
<column name="grnid" length="20" />
</property>
<property name="totQty" type="java.lang.Float">
<column name="Totqty" precision="12" scale="0" />
</property>
<property name="refNo" type="java.lang.String">
<column name="Refno" length="20" />
</property>
<property name="trntype" type="java.lang.String">
<column name="trntype" length="2" />
</property>
<property name="discount" type="java.lang.Double">
<column name="discount" precision="15" />
</property>
<property name="empid" type="java.lang.String">
<column name="empid" length="20" />
</property>
<property name="tdiscamt" type="java.lang.Double">
<column name="tdiscamt" />
</property>
<property name="tdiscpc" type="java.lang.Double">
<column name="tdiscpc" />
</property>
<property name="pack" type="java.lang.String">
<column name="pack" length="10" not-null="true" />
</property>
<property name="supplierid" type="java.lang.String">
<column name="supplierid" length="45" not-null="true" />
</property>
<property name="cashdiscpercent" type="java.lang.Double">
<column name="cashdiscpercent" precision="5" />
</property>
<property name="commpercent" type="java.lang.Double">
<column name="commpercent" precision="5" />
</property>
<property name="distdiscpercent" type="java.lang.Double">
<column name="distdiscpercent" precision="5" />
</property>
<property name="schemediscpercent" type="java.lang.Double">
<column name="schemediscpercent" precision="5" />
</property>
<property name="dispdiscpercent" type="java.lang.Double">
<column name="dispdiscpercent" precision="5" />
</property>
<property name="miscpercent" type="java.lang.Double">
<column name="miscpercent" precision="5" />
</property>
<property name="rounding" type="java.lang.Double">
<column name="rounding" precision="5" />
</property>
<property name="adj" type="java.lang.Double">
<column name="adj" precision="10" />
</property>
<property name="indfld" type="java.lang.Integer">
<column name="indfld" />
</property>
<property name="pts" type="java.lang.Double">
<column name="pts" precision="10" />
</property>
<property name="refdate" type="java.lang.String">
<column name="refdate" length="45" />
</property>
<property name="updated" type="java.lang.Byte">
<column name="updated" />
</property>
<property name="qty" type="java.lang.Float">
<column name="qty" precision="12" scale="0" />
</property>
<property name="flag" type="java.lang.Byte">
<column name="flag" not-null="true" />
</property>
<property name="remark" type="java.lang.String">
<column name="remark" length="100" />
</property>
</class>
</hibernate-mapping>




Code between sessionFactory.openSession() and session.close():
try{
session = HibernateSessionFactory.openSession();
session.beginTransaction();
grnbean=(Ssagrtransactions) grnitr.next();
// grnbean is bean object of SSaGrtransactions class
SSAGrnDAO.dao.saveGRNBean(grnbean);
session.commit();
}
catch (PersistenceException e) {
temp.setEmpid("fail");
temp.setOperation("fail");
temp.setShopid("fail");
temp.setTimestamp(0);
session.rollback();
throw e;


} catch (Exception e) {

temp.setEmpid("fail");
temp.setOperation("fail");
temp.setShopid("fail");
temp.setTimestamp(0);

session.rollback();
e.printStackTrace();
throw new PersistenceException(e.getMessage(), e);

} finally {
session.close();

}


Full stack trace of any exception that occurs:
no exception

Name and version of the database you are using:
MySql 5.0


Thank you,
Sudheer Tumu.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 27, 2008 9:41 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Well, I think you're seeing the normal behavior of the Identity primary key generation strategy with Hibernate and MySQL.

There are other options for generating primary keys. If you want more control over primary key generations, you can use a SEQUENCE or TABLE GenerationType:

http://jpa.ezhibernate.com/Javacode/lea ... jpamapping

Quote:
there are actually four different strategies for having the primary key generated by the database. Those four options are:

* AUTO
* IDENTITY
* TABLE
* SEQUENCE

javax.persistence.GenerationType.AUTO

The AUTO generation strategy is the default, and this setting simply chooses the primary key generation strategy that is the default for the database in question, which quite typically is IDENTITY, although it might be TABLE or SEQUENCE depending upon how the database is configured. The AUTO strategy is typically recommended, as it makes your code and your applications most portable.
javax.persistence.GenerationType.IDENTITY

The IDENTITY option simply allows the database to generate a unique primary key for your application. No sequence or table is used to maintain the primary key information, but instead, the database will just pick an appropriate, unique number for Hibernate to assign to the primary key of the entity. With MySQL, the first lowest numbered primary key available in the table in question is chosen, although this behavior may differ from database to database.
javax.persistence.GenerationType.Sequence

Some database vendors support the use of a database sequence object for maintaining primary keys. To use a sequence, you set the GenerationType strategy to SEQUENCE, specify the name of the generator annotation, and then provide the @SequenceGenerator annotation that has attributes for defining both the name of the sequence annotation, and the name of the actual sequence object in the database.
Here's what the getId() method of the Snafu class would look like if we used a SEQUENCE GenerationType:

@Id
@SequenceGenerator(name="s1", sequenceName="SEQ")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s1")
public long getId() {return id;}

javax.persistence.GenerationType.TABLE

The TABLE GenerationType allocates a separate database table to keep track of the generation of unique ids. To facilitate the description of the table to be used, the TABLE strategy works hand in hand with the @TableGenerator annotation. So, if our Snafu class was to use a separate table for managing primary keys, the getId() method annotation would look like this:

@Id
@TableGenerator(name="tg", table="pk_table",
pkColumnName="name", valueColumnName="value",
allocationSize=10
)@GeneratedValue(strategy=GenerationType.TABLE, generator="tg")
public long getId() {return id;}


With this @TableGenerator annotation, a separate table in the database named pk_table would be created with two columns, one called name, and the other called value. The name will simply be Snafu, the name of the class using the table, indicating the class for which the key is being maintained. The pkColumnValue will maintain the current iteration of key generation. Furthermore, the allocationSize determines the increment size of the generated primary keys for a new thread.


http://jpa.thebookonhibernate.com/Javacode/learn.jsp?tutorial=12oneclasstoonetablejpamapping

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 27, 2008 9:47 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Well, I think you're seeing the normal behavior of the Identity primary key generation strategy with Hibernate and MySQL.

There are other options for generating primary keys. If you want more control over primary key generations, you can use a SEQUENCE or TABLE GenerationType:

http://jpa.ezhibernate.com/Javacode/lea ... jpamapping

Quote:
there are actually four different strategies for having the primary key generated by the database. Those four options are:

* AUTO
* IDENTITY
* TABLE
* SEQUENCE

javax.persistence.GenerationType.AUTO

The AUTO generation strategy is the default, and this setting simply chooses the primary key generation strategy that is the default for the database in question, which quite typically is IDENTITY, although it might be TABLE or SEQUENCE depending upon how the database is configured. The AUTO strategy is typically recommended, as it makes your code and your applications most portable.
javax.persistence.GenerationType.IDENTITY

The IDENTITY option simply allows the database to generate a unique primary key for your application. No sequence or table is used to maintain the primary key information, but instead, the database will just pick an appropriate, unique number for Hibernate to assign to the primary key of the entity. With MySQL, the first lowest numbered primary key available in the table in question is chosen, although this behavior may differ from database to database.
javax.persistence.GenerationType.Sequence

Some database vendors support the use of a database sequence object for maintaining primary keys. To use a sequence, you set the GenerationType strategy to SEQUENCE, specify the name of the generator annotation, and then provide the @SequenceGenerator annotation that has attributes for defining both the name of the sequence annotation, and the name of the actual sequence object in the database.
Here's what the getId() method of the Snafu class would look like if we used a SEQUENCE GenerationType:

@Id
@SequenceGenerator(name="s1", sequenceName="SEQ")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s1")
public long getId() {return id;}

javax.persistence.GenerationType.TABLE

The TABLE GenerationType allocates a separate database table to keep track of the generation of unique ids. To facilitate the description of the table to be used, the TABLE strategy works hand in hand with the @TableGenerator annotation. So, if our Snafu class was to use a separate table for managing primary keys, the getId() method annotation would look like this:

@Id
@TableGenerator(name="tg", table="pk_table",
pkColumnName="name", valueColumnName="value",
allocationSize=10
)@GeneratedValue(strategy=GenerationType.TABLE, generator="tg")
public long getId() {return id;}


With this @TableGenerator annotation, a separate table in the database named pk_table would be created with two columns, one called name, and the other called value. The name will simply be Snafu, the name of the class using the table, indicating the class for which the key is being maintained. The pkColumnValue will maintain the current iteration of key generation. Furthermore, the allocationSize determines the increment size of the generated primary keys for a new thread.


http://jpa.thebookonhibernate.com/Javacode/learn.jsp?tutorial=12oneclasstoonetablejpamapping

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 03, 2008 12:46 am 
Newbie

Joined: Fri Jun 27, 2008 8:16 am
Posts: 2
Hi Cameron,
Thanks for your help. I have followed your suggestions, but not able to solve my problem.

I am using Mysql Database.

how come an "IDENTITY" column increases its value even when the session is rolling back? it should do it when the session commits only.No data is getting inserted into tables but just auto increment index value is increasing.

If I go for "AUTO", i am getting following exception
org.hibernate.MappingException: could not instantiate id generator
at org.hibernate.id.IdentifierGeneratorFactory.create(IdentifierGeneratorFactory.java:92)
at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:151)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:178)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1005)
at com.dao.hibernate.HibernateSessionFactory.<clinit>(HibernateSessionFactory.java:65)
at com.server.impl.LocalTaskMangementService.updateSSAGrn(LocalTaskMangementService.java:181)
at com.hms.SSAGrn.processRequest(SSAGrn.java:85)
at com.hms.SSAGrn.doPost(SSAGrn.java:148)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.MappingException: could not interpret id generator strategy: auto
at org.hibernate.id.IdentifierGeneratorFactory.getIdentifierGeneratorClass(IdentifierGeneratorFactory.java:103)
at org.hibernate.id.IdentifierGeneratorFactory.create(IdentifierGeneratorFactory.java:86)


Mysql does not support "SEQUENCE" datatype.


I can not use TABLE datatype.

I just need a small thing, the auto increment index should not change when the session is rolls back.

Any body please help me

Thank you,
Sudheer Tumu.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 03, 2008 2:28 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Here is an explanation of why the auto-increment counter in MySQL can't be rolled back.

http://bugs.mysql.com/bug.php?id=6714


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 04, 2008 1:26 pm 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Sweet! Thanks for the bug post!

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


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