[hibernate-commits] Hibernate SVN: r19586 - in core/trunk/core/src: test/java/org/hibernate/id and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri May 21 17:20:36 EDT 2010


Author: steve.ebersole at jboss.com
Date: 2010-05-21 17:20:36 -0400 (Fri, 21 May 2010)
New Revision: 19586

Added:
   core/trunk/core/src/test/java/org/hibernate/id/TableHiLoGeneratorTest.java
Modified:
   core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java
Log:
HHH-5253 - TableHiLoGenerator does not increment hi-value any more when lo-range es exhausted


Modified: core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java	2010-05-21 21:19:56 UTC (rev 19585)
+++ core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java	2010-05-21 21:20:36 UTC (rev 19586)
@@ -1,10 +1,10 @@
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
  * indicated by the @author tags or express copyright attribution
  * statements applied by the authors.  All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
+ * distributed under license by Red Hat Inc.
  *
  * This copyrighted material is made available to anyone wishing to use, modify,
  * copy, or redistribute it subject to the terms and conditions of the GNU
@@ -20,17 +20,16 @@
  * Free Software Foundation, Inc.
  * 51 Franklin Street, Fifth Floor
  * Boston, MA  02110-1301  USA
- *
  */
 package org.hibernate.id;
 
 import java.io.Serializable;
 import java.util.Properties;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.hibernate.dialect.Dialect;
 import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.enhanced.AccessCallback;
+import org.hibernate.id.enhanced.OptimizerFactory;
 import org.hibernate.type.Type;
 import org.hibernate.util.PropertiesHelper;
 
@@ -38,7 +37,7 @@
  * <b>hilo</b><br>
  * <br>
  * An <tt>IdentifierGenerator</tt> that returns a <tt>Long</tt>, constructed using
- * a hi/lo algorithm. The hi value MUST be fetched in a seperate transaction
+ * a hi/lo algorithm. The hi value MUST be fetched in a separate transaction
  * to the <tt>Session</tt> transaction so the generator must be able to obtain
  * a new connection and commit it. Hence this implementation may not
  * be used  when the user is supplying connections. In this
@@ -51,26 +50,25 @@
  * @author Gavin King
  */
 public class TableHiLoGenerator extends TableGenerator {
-
 	/**
 	 * The max_lo parameter
 	 */
 	public static final String MAX_LO = "max_lo";
 
+	private OptimizerFactory.LegacyHiLoAlgorithmOptimizer hiloOptimizer;
+
 	private int maxLo;
-	private int lo;
 
-	private IntegralDataTypeHolder value;
-
-	private static final Logger log = LoggerFactory.getLogger(TableHiLoGenerator.class);
-
 	public void configure(Type type, Properties params, Dialect d) {
 		super.configure(type, params, d);
 		maxLo = PropertiesHelper.getInt(MAX_LO, params, Short.MAX_VALUE);
-		lo = maxLo + 1; // so we "clock over" on the first invocation
+
+		if ( maxLo >= 1 ) {
+			hiloOptimizer = new OptimizerFactory.LegacyHiLoAlgorithmOptimizer( type.getReturnedClass(), maxLo );
+		}
 	}
 
-	public synchronized Serializable generate(SessionImplementor session, Object obj) {
+	public synchronized Serializable generate(final SessionImplementor session, Object obj) {
 		// maxLo < 1 indicates a hilo generator with no hilo :?
         if ( maxLo < 1 ) {
 			//keep the behavior consistent even for boundary usages
@@ -81,16 +79,13 @@
 			return value.makeValue();
 		}
 
-		if ( lo > maxLo ) {
-			IntegralDataTypeHolder hiVal = generateHolder( session );
-			lo = ( hiVal.eq( 0 ) ) ? 1 : 0;
-			value = hiVal.copy().multiplyBy( maxLo+1 ).add( lo );
-			if ( log.isDebugEnabled() ) {
-				log.debug("new hi value: " + hiVal);
-			}
-		}
-
-		return value.makeValueThenIncrement();
+		return hiloOptimizer.generate(
+				new AccessCallback() {
+					public IntegralDataTypeHolder getNextValue() {
+						return generateHolder( session );
+					}
+				}
+		);
 	}
 
 }

Copied: core/trunk/core/src/test/java/org/hibernate/id/TableHiLoGeneratorTest.java (from rev 19581, core/trunk/core/src/test/java/org/hibernate/id/SequenceHiLoGeneratorTest.java)
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/id/TableHiLoGeneratorTest.java	                        (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/id/TableHiLoGeneratorTest.java	2010-05-21 21:20:36 UTC (rev 19586)
@@ -0,0 +1,170 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.id;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.hibernate.Hibernate;
+import org.hibernate.Session;
+import org.hibernate.TestingDatabaseInfo;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.cfg.ObjectNameNormalizer;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.H2Dialect;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.impl.SessionImpl;
+import org.hibernate.jdbc.Work;
+import org.hibernate.mapping.SimpleAuxiliaryDatabaseObject;
+
+/**
+ * I went back to 3.3 source and grabbed the code/logic as it existed back then and crafted this
+ * unit test so that we can make sure the value keep being generated in the expected manner
+ *
+ * @author Steve Ebersole
+ */
+ at SuppressWarnings({ "deprecation" })
+public class TableHiLoGeneratorTest extends TestCase {
+	private static final String GEN_TABLE = "generator_table";
+	private static final String GEN_COLUMN = TableHiLoGenerator.DEFAULT_COLUMN_NAME;
+
+	private Configuration cfg;
+	private SessionFactoryImplementor sessionFactory;
+	private TableHiLoGenerator generator;
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		Properties properties = new Properties();
+		properties.setProperty( TableHiLoGenerator.TABLE, GEN_TABLE );
+		properties.setProperty( TableHiLoGenerator.COLUMN, GEN_COLUMN );
+		properties.setProperty( TableHiLoGenerator.MAX_LO, "3" );
+		properties.put(
+				PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
+				new ObjectNameNormalizer() {
+					@Override
+					protected boolean isUseQuotedIdentifiersGlobally() {
+						return false;
+					}
+
+					@Override
+					protected NamingStrategy getNamingStrategy() {
+						return cfg.getNamingStrategy();
+					}
+				}
+		);
+
+		Dialect dialect = new H2Dialect();
+
+		generator = new TableHiLoGenerator();
+		generator.configure( Hibernate.LONG, properties, dialect );
+
+		cfg = TestingDatabaseInfo.buildBaseConfiguration()
+				.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
+		cfg.addAuxiliaryDatabaseObject(
+				new SimpleAuxiliaryDatabaseObject(
+						generator.sqlCreateStrings( dialect )[0],
+						generator.sqlDropStrings( dialect )[0]
+				)
+		);
+
+		cfg.addAuxiliaryDatabaseObject(
+				new SimpleAuxiliaryDatabaseObject(
+						generator.sqlCreateStrings( dialect )[1],
+						null
+				)
+		);
+
+		sessionFactory = (SessionFactoryImplementor) cfg.buildSessionFactory();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		if ( sessionFactory != null ) {
+			sessionFactory.close();
+		}
+
+		super.tearDown();
+	}
+
+	public void testHiLoAlgorithm() {
+		SessionImpl session = (SessionImpl) sessionFactory.openSession();
+		session.beginTransaction();
+
+		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		// initially sequence should be uninitialized
+		assertEquals( 0L, extractInDatabaseValue( session ) );
+
+		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		Long generatedValue = (Long) generator.generate( session, null );
+		assertEquals( 1L, generatedValue.longValue() );
+		assertEquals( 1L, extractInDatabaseValue( session ) );
+
+		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		generatedValue = (Long) generator.generate( session, null );
+		assertEquals( 2L, generatedValue.longValue() );
+		assertEquals( 1L, extractInDatabaseValue( session ) );
+
+		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		generatedValue = (Long) generator.generate( session, null );
+		assertEquals( 3L, generatedValue.longValue() );
+		assertEquals( 1L, extractInDatabaseValue( session ) );
+
+		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		generatedValue = (Long) generator.generate( session, null );
+		assertEquals( 4L, generatedValue.longValue() );
+		assertEquals( 2L, extractInDatabaseValue( session ) );
+
+		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		generatedValue = (Long) generator.generate( session, null );
+		assertEquals( 5L, generatedValue.longValue() );
+		assertEquals( 2L, extractInDatabaseValue( session ) );
+
+		session.getTransaction().commit();
+		session.close();
+	}
+
+	private long extractInDatabaseValue(Session session) {
+		class WorkImpl implements Work {
+			private long value;
+			public void execute(Connection connection) throws SQLException {
+				PreparedStatement query = connection.prepareStatement( "select " + GEN_COLUMN + " from " + GEN_TABLE );
+				ResultSet resultSet = query.executeQuery();
+				resultSet.next();
+				value = resultSet.getLong( 1 );
+			}
+		}
+		WorkImpl work = new WorkImpl();
+		session.doWork( work );
+		return work.value;
+	}
+}
\ No newline at end of file



More information about the hibernate-commits mailing list