ok i created my Custom IdGenerator whicih closely resembles the hilo strategy. It is :
package com.sen.util;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.MappingException;
import net.sf.hibernate.dialect.Dialect;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.id.Configurable;
import net.sf.hibernate.id.IdentifierGenerationException;
import net.sf.hibernate.id.IdentifierGenerator;
import net.sf.hibernate.type.Type;
import net.sf.hibernate.util.PropertiesHelper;
public class MyTestIdGenerator implements IdentifierGenerator, Configurable {
/**
* The keycode parameter
* The keycode specified will be used for the type of key (default: GLOBALID)
*/
public static final String KEYCODE = "keycode";
private static final Log log = LogFactory.getLog(MyTestIdGenerator.class);
private String keycodeName;
private String query;
private String update;
/* (non-Javadoc)
* @see net.sf.hibernate.id.IdentifierGenerator#generate(net.sf.hibernate.engine.SessionImplementor, java.lang.Object)
*/
public synchronized Serializable generate(SessionImplementor session, Object object)
throws SQLException, HibernateException {
// This has to be done using a different connection to the
// containing transaction because the new hi value must
// remain valid even if the containing transaction rolls
// back
Connection connection = session.getBatcher().openConnection();
int result;
int rows;
try {
connection.setAutoCommit(false);
do {
// The loop ensures atomicity of the
// select + update even for no transaction
// or read committed isolation level
PreparedStatement qps = connection.prepareStatement(query);
try {
ResultSet rs = qps.executeQuery();
if ( !rs.next() ) {
String err = "could not read a hi value - you need to populate the table: SYSTEM_KEYS";
log.error(err);
throw new IdentifierGenerationException(err);
}
result = rs.getInt(1);
rs.close();
}
catch (SQLException sqle) {
log.error("could not read a hi value", sqle);
throw sqle;
}
finally {
qps.close();
}
System.out.println( "MyTestIdGenerator: generate: result = " + result );
PreparedStatement ups = connection.prepareStatement(update);
try {
ups.setInt( 1, result + 1 );
ups.setInt( 2, result );
rows = ups.executeUpdate();
}
catch (SQLException sqle) {
log.error("could not update hi value in: SYSTEM_KEYS", sqle);
throw sqle;
}
finally {
ups.close();
}
}
while (rows==0);
connection.commit();
return new Integer(result);
}
finally {
session.getBatcher().closeConnection(connection);
}
}
/* (non-Javadoc)
* @see net.sf.hibernate.id.Configurable#configure(net.sf.hibernate.type.Type, java.util.Properties, net.sf.hibernate.dialect.Dialect)
*/
public void configure(Type type, Properties params, Dialect dialect)
throws MappingException {
this.keycodeName = PropertiesHelper.getString(KEYCODE, params, "GLOBALID");
// build the query statement
query = "select NEXT_KEY from SYSTEM_KEYS where KEY_CODE = '" + keycodeName + "'";
// build the update statement
update = "update SYSTEM_KEYS set NEXT_KEY = ? where NEXT_KEY = ?" + " and KEY_CODE = '" + keycodeName + "'";
System.out.println( "MyTestIdGenerator.java: configure: keycodeName = " + keycodeName );
System.out.println( "MyTestIdGenerator.java: configure: query = " + query );
System.out.println( "MyTestIdGenerator.java: configure: update = " + update );
}
}
Change my Location.hbm.xml to use the new Custom IdGenerator :
<id
name="locationId"
type="java.lang.Integer"
column="location_id"
>
<generator class="com.sen.util.MyTestIdGenerator">
<param name="keycode">LOCATION</param>
</generator>
</id>
In my java code I am not using the setId() method of Location class:
Location aLocation = new Location();
aLocation.setName("Detroit");
aLocationDAO.createLocation( aLocation );
When I try to update, I get this error message :
2004-12-09 18:00:19,558 DEBUG [net.sf.hibernate.util.JDBCExceptionReporter] SQL Exception
java.sql.SQLException: You cannot set autocommit during a managed transaction!
at org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:440)
at org.jboss.resource.adapter.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:446)
at com.sen.util.MyTestIdGenerator.generate(MyTestIdGenerator.java:52)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:765)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:738)
at com.sen.main.dao.base.DAOHibernate.createObject(DAOHibernate.java:45)
at com.sen.main.dao.hibernate.LocationDAOHibernate.createLocation(LocationDAOHibernate.java:57)
at org.apache.jsp._2_jsp._jspService(_2_jsp.java:87)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:137)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:210)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:220)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2417)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:197)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:781)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:549)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
at java.lang.Thread.run(Thread.java:534)
2004-12-09 18:00:19,558 WARN [net.sf.hibernate.util.JDBCExceptionReporter] SQL Error: 0, SQLState: null
2004-12-09 18:00:19,558 ERROR [net.sf.hibernate.util.JDBCExceptionReporter] You cannot set autocommit during a managed transaction!
2004-12-09 18:00:19,574 ERROR [net.sf.hibernate.util.JDBCExceptionReporter] Could not save object
java.sql.SQLException: You cannot set autocommit during a managed transaction!
at org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:440)
at org.jboss.resource.adapter.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:446)
at com.sen.util.MyTestIdGenerator.generate(MyTestIdGenerator.java:52)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:765)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:738)
at com.sen.main.dao.base.DAOHibernate.createObject(DAOHibernate.java:45)
at com.sen.main.dao.hibernate.LocationDAOHibernate.createLocation(LocationDAOHibernate.java:57)
at org.apache.jsp._2_jsp._jspService(_2_jsp.java:87)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:137)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:210)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:220)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2417)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:197)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:781)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:549)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
at java.lang.Thread.run(Thread.java:534)
2004-12-09 18:00:19,590 INFO [STDOUT] Trying to rollback database transaction of this thread.
2004-12-09 18:00:19,590 DEBUG [net.sf.hibernate.transaction.JTATransaction] rollback
2004-12-09 18:00:19,590 DEBUG [net.sf.hibernate.impl.SessionImpl] transaction completion
2004-12-09 18:00:19,590 INFO [STDOUT] HibernateSession: rollbackTransaction() successfully executed.
2004-12-09 18:00:19,590 INFO [STDOUT] HibernateSession: Closing Session of this thread.
2004-12-09 18:00:19,590 DEBUG [net.sf.hibernate.impl.SessionImpl] closing session
2004-12-09 18:00:19,590 INFO [STDOUT] HibernateSession: closeSession() successfully executed.
2004-12-09 18:00:19,621 DEBUG [net.sf.hibernate.impl.SessionImpl] running Session.finalize()
Any reason? Thanks
|