[hibernate-commits] Hibernate SVN: r18789 - in core/trunk: core/src/main/java/org/hibernate/id and 11 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Fri Feb 12 01:22:53 EST 2010
Author: steve.ebersole at jboss.com
Date: 2010-02-12 01:22:52 -0500 (Fri, 12 Feb 2010)
New Revision: 18789
Added:
core/trunk/core/src/main/java/org/hibernate/id/IntegralDataTypeHolder.java
core/trunk/core/src/test/java/org/hibernate/id/
core/trunk/core/src/test/java/org/hibernate/id/AbstractHolderTest.java
core/trunk/core/src/test/java/org/hibernate/id/BigDecimalHolderTest.java
core/trunk/core/src/test/java/org/hibernate/id/BigIntegerHolderTest.java
core/trunk/core/src/test/java/org/hibernate/id/LongHolderTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/BigIntegerIncrementGeneratorTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/Entity.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/Mapping.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/BigIntegerSequenceGeneratorTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/Entity.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/Mapping.hbm.xml
Modified:
core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java
core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java
core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java
core/trunk/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java
core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java
core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/BasicForcedTableSequenceTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/HiLoForcedTableSequenceTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/PooledForcedTableSequenceTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/BasicSequenceTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/HiLoSequenceTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/PooledSequenceTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/BasicTableTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/HiLoTableTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/PooledTableTest.java
Log:
HHH-4905 - Allow consistent handling of numeric primary key values by any integral data type
Modified: core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -91,7 +91,9 @@
}
}
public Object getDefaultValue(Object currentValue) {
- return IdentifierGeneratorHelper.createNumber( -1l, currentValue.getClass() );
+ return IdentifierGeneratorHelper.getIntegralDataTypeHolder( currentValue.getClass() )
+ .initialize( -1L )
+ .makeValue();
}
public String toString() {
return "VERSION_NEGATIVE";
Modified: core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -25,6 +25,9 @@
package org.hibernate.id;
import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -119,10 +122,17 @@
else if ( clazz == String.class ) {
return rs.getString( 1 );
}
+ else if ( clazz == BigInteger.class ) {
+ return rs.getBigDecimal( 1 ).setScale( 0, BigDecimal.ROUND_UNNECESSARY ).toBigInteger();
+ }
+ else if ( clazz == BigDecimal.class ) {
+ return rs.getBigDecimal( 1 ).setScale( 0, BigDecimal.ROUND_UNNECESSARY );
+ }
else {
- throw new IdentifierGenerationException( "this id generator generates long, integer, short or string" );
+ throw new IdentifierGenerationException(
+ "unrecognized id type : " + type.getName() + " -> " + clazz.getName()
+ );
}
-
}
/**
@@ -130,8 +140,12 @@
*
* @param value The primitive value to wrap.
* @param clazz The Java numeric type in which to wrap the value.
+ *
* @return The wrapped type.
+ *
* @throws IdentifierGenerationException Indicates an unhandled 'clazz'.
+ *
+ * @deprecated Use the {@link #getIntegralDataTypeHolder holders} instead.
*/
public static Number createNumber(long value, Class clazz) throws IdentifierGenerationException {
if ( clazz == Long.class ) {
@@ -144,10 +158,513 @@
return new Short( ( short ) value );
}
else {
- throw new IdentifierGenerationException( "this id generator generates long, integer, short" );
+ throw new IdentifierGenerationException( "unrecognized id type : " + clazz.getName() );
}
}
+ public static IntegralDataTypeHolder getIntegralDataTypeHolder(Class integralType) {
+ if ( integralType == Long.class
+ || integralType == Integer.class
+ || integralType == Short.class ) {
+ return new BasicHolder( integralType );
+ }
+ else if ( integralType == BigInteger.class ) {
+ return new BigIntegerHolder();
+ }
+ else if ( integralType == BigDecimal.class ) {
+ return new BigDecimalHolder();
+ }
+ else {
+ throw new IdentifierGenerationException(
+ "Unknown integral data type for ids : " + integralType.getName()
+ );
+ }
+ }
+
+ public static long extractLong(IntegralDataTypeHolder holder) {
+ if ( holder.getClass() == BasicHolder.class ) {
+ ( (BasicHolder) holder ).checkInitialized();
+ return ( (BasicHolder) holder ).value;
+ }
+ else if ( holder.getClass() == BigIntegerHolder.class ) {
+ ( (BigIntegerHolder) holder ).checkInitialized();
+ return ( (BigIntegerHolder) holder ).value.longValue();
+ }
+ else if ( holder.getClass() == BigDecimalHolder.class ) {
+ ( (BigDecimalHolder) holder ).checkInitialized();
+ return ( (BigDecimalHolder) holder ).value.longValue();
+ }
+ throw new IdentifierGenerationException( "Unknown IntegralDataTypeHolder impl [" + holder + "]" );
+ }
+
+ public static BigInteger extractBigInteger(IntegralDataTypeHolder holder) {
+ if ( holder.getClass() == BasicHolder.class ) {
+ ( (BasicHolder) holder ).checkInitialized();
+ return BigInteger.valueOf( ( (BasicHolder) holder ).value );
+ }
+ else if ( holder.getClass() == BigIntegerHolder.class ) {
+ ( (BigIntegerHolder) holder ).checkInitialized();
+ return ( (BigIntegerHolder) holder ).value;
+ }
+ else if ( holder.getClass() == BigDecimalHolder.class ) {
+ ( (BigDecimalHolder) holder ).checkInitialized();
+ // scale should already be set...
+ return ( (BigDecimalHolder) holder ).value.toBigInteger();
+ }
+ throw new IdentifierGenerationException( "Unknown IntegralDataTypeHolder impl [" + holder + "]" );
+ }
+
+ public static BigDecimal extractBigDecimal(IntegralDataTypeHolder holder) {
+ if ( holder.getClass() == BasicHolder.class ) {
+ ( (BasicHolder) holder ).checkInitialized();
+ return BigDecimal.valueOf( ( (BasicHolder) holder ).value );
+ }
+ else if ( holder.getClass() == BigIntegerHolder.class ) {
+ ( (BigIntegerHolder) holder ).checkInitialized();
+ return new BigDecimal( ( (BigIntegerHolder) holder ).value );
+ }
+ else if ( holder.getClass() == BigDecimalHolder.class ) {
+ ( (BigDecimalHolder) holder ).checkInitialized();
+ // scale should already be set...
+ return ( (BigDecimalHolder) holder ).value;
+ }
+ throw new IdentifierGenerationException( "Unknown IntegralDataTypeHolder impl [" + holder + "]" );
+ }
+
+ public static class BasicHolder implements IntegralDataTypeHolder {
+ private final Class exactType;
+ private long value = Long.MIN_VALUE;
+
+ public BasicHolder(Class exactType) {
+ this.exactType = exactType;
+ if ( exactType != Long.class && exactType != Integer.class && exactType != Short.class ) {
+ throw new IdentifierGenerationException( "Invalid type for basic integral holder : " + exactType );
+ }
+ }
+
+ public long getActualLongValue() {
+ return value;
+ }
+
+ public IntegralDataTypeHolder initialize(long value) {
+ this.value = value;
+ return this;
+ }
+
+ public IntegralDataTypeHolder initialize(ResultSet resultSet, long defaultValue) throws SQLException {
+ long value = resultSet.getLong( 1 );
+ if ( resultSet.wasNull() ) {
+ value = defaultValue;
+ }
+ return initialize( value );
+ }
+
+ public void bind(PreparedStatement preparedStatement, int position) throws SQLException {
+ // TODO : bind it as 'exact type'? Not sure if that gains us anything...
+ preparedStatement.setLong( position, value );
+ }
+
+ public IntegralDataTypeHolder increment() {
+ checkInitialized();
+ value++;
+ return this;
+ }
+
+ private void checkInitialized() {
+ if ( value == Long.MIN_VALUE ) {
+ throw new IdentifierGenerationException( "integral holder was not initialized" );
+ }
+ }
+
+ public IntegralDataTypeHolder add(long addend) {
+ checkInitialized();
+ value += addend;
+ return this;
+ }
+
+ public IntegralDataTypeHolder decrement() {
+ checkInitialized();
+ value--;
+ return this;
+ }
+
+ public IntegralDataTypeHolder subtract(long subtrahend) {
+ checkInitialized();
+ value -= subtrahend;
+ return this;
+ }
+
+ public IntegralDataTypeHolder multiplyBy(IntegralDataTypeHolder factor) {
+ return multiplyBy( extractLong( factor ) );
+ }
+
+ public IntegralDataTypeHolder multiplyBy(long factor) {
+ checkInitialized();
+ value *= factor;
+ return this;
+ }
+
+ public boolean eq(IntegralDataTypeHolder other) {
+ return eq( extractLong( other ) );
+ }
+
+ public boolean eq(long value) {
+ checkInitialized();
+ return this.value == value;
+ }
+
+ public boolean lt(IntegralDataTypeHolder other) {
+ return lt( extractLong( other ) );
+ }
+
+ public boolean lt(long value) {
+ checkInitialized();
+ return this.value < value;
+ }
+
+ public boolean gt(IntegralDataTypeHolder other) {
+ return gt( extractLong( other ) );
+ }
+
+ public boolean gt(long value) {
+ checkInitialized();
+ return this.value > value;
+ }
+
+ public IntegralDataTypeHolder copy() {
+ BasicHolder copy = new BasicHolder( exactType );
+ copy.value = value;
+ return copy;
+ }
+
+ public Number makeValue() {
+ // TODO : should we check for truncation?
+ checkInitialized();
+ if ( exactType == Long.class ) {
+ return new Long( value );
+ }
+ else if ( exactType == Integer.class ) {
+ return new Integer( ( int ) value );
+ }
+ else {
+ return new Short( ( short ) value );
+ }
+ }
+
+ public Number makeValueThenIncrement() {
+ final Number result = makeValue();
+ value++;
+ return result;
+ }
+
+ public Number makeValueThenAdd(long addend) {
+ final Number result = makeValue();
+ value += addend;
+ return result;
+ }
+
+ public String toString() {
+ return "BasicHolder[" + exactType.getName() + "[" + value + "]]";
+ }
+
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+
+ BasicHolder that = (BasicHolder) o;
+
+ return value == that.value;
+ }
+
+ public int hashCode() {
+ return (int) ( value ^ ( value >>> 32 ) );
+ }
+ }
+
+ public static class BigIntegerHolder implements IntegralDataTypeHolder {
+ private BigInteger value;
+
+ public IntegralDataTypeHolder initialize(long value) {
+ this.value = BigInteger.valueOf( value );
+ return this;
+ }
+
+ public IntegralDataTypeHolder initialize(ResultSet resultSet, long defaultValue) throws SQLException {
+ final BigDecimal rsValue = resultSet.getBigDecimal( 1 );
+ if ( resultSet.wasNull() ) {
+ return initialize( defaultValue );
+ }
+ this.value = rsValue.setScale( 0, BigDecimal.ROUND_UNNECESSARY ).toBigInteger();
+ return this;
+ }
+
+ public void bind(PreparedStatement preparedStatement, int position) throws SQLException {
+ preparedStatement.setBigDecimal( position, new BigDecimal( value ) );
+ }
+
+ public IntegralDataTypeHolder increment() {
+ checkInitialized();
+ value = value.add( BigInteger.ONE );
+ return this;
+ }
+
+ private void checkInitialized() {
+ if ( value == null ) {
+ throw new IdentifierGenerationException( "integral holder was not initialized" );
+ }
+ }
+
+ public IntegralDataTypeHolder add(long increment) {
+ checkInitialized();
+ value = value.add( BigInteger.valueOf( increment ) );
+ return this;
+ }
+
+ public IntegralDataTypeHolder decrement() {
+ checkInitialized();
+ value = value.subtract( BigInteger.ONE );
+ return this;
+ }
+
+ public IntegralDataTypeHolder subtract(long subtrahend) {
+ checkInitialized();
+ value = value.subtract( BigInteger.valueOf( subtrahend ) );
+ return this;
+ }
+
+ public IntegralDataTypeHolder multiplyBy(IntegralDataTypeHolder factor) {
+ checkInitialized();
+ value = value.multiply( extractBigInteger( factor ) );
+ return this;
+ }
+
+ public IntegralDataTypeHolder multiplyBy(long factor) {
+ checkInitialized();
+ value = value.multiply( BigInteger.valueOf( factor ) );
+ return this;
+ }
+
+ public boolean eq(IntegralDataTypeHolder other) {
+ checkInitialized();
+ return value.compareTo( extractBigInteger( other ) ) == 0;
+ }
+
+ public boolean eq(long value) {
+ checkInitialized();
+ return this.value.compareTo( BigInteger.valueOf( value ) ) == 0;
+ }
+
+ public boolean lt(IntegralDataTypeHolder other) {
+ checkInitialized();
+ return value.compareTo( extractBigInteger( other ) ) < 0;
+ }
+
+ public boolean lt(long value) {
+ checkInitialized();
+ return this.value.compareTo( BigInteger.valueOf( value ) ) < 0;
+ }
+
+ public boolean gt(IntegralDataTypeHolder other) {
+ checkInitialized();
+ return value.compareTo( extractBigInteger( other ) ) > 0;
+ }
+
+ public boolean gt(long value) {
+ checkInitialized();
+ return this.value.compareTo( BigInteger.valueOf( value ) ) > 0;
+ }
+
+ public IntegralDataTypeHolder copy() {
+ BigIntegerHolder copy = new BigIntegerHolder();
+ copy.value = value;
+ return copy;
+ }
+
+ public Number makeValue() {
+ checkInitialized();
+ return value;
+ }
+
+ public Number makeValueThenIncrement() {
+ final Number result = makeValue();
+ value = value.add( BigInteger.ONE );
+ return result;
+ }
+
+ public Number makeValueThenAdd(long addend) {
+ final Number result = makeValue();
+ value = value.add( BigInteger.valueOf( addend ) );
+ return result;
+ }
+
+ public String toString() {
+ return "BigIntegerHolder[" + value + "]";
+ }
+
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+
+ BigIntegerHolder that = (BigIntegerHolder) o;
+
+ return this.value == null
+ ? that.value == null
+ : value.equals( that.value );
+ }
+
+ public int hashCode() {
+ return value != null ? value.hashCode() : 0;
+ }
+ }
+
+ public static class BigDecimalHolder implements IntegralDataTypeHolder {
+ private BigDecimal value;
+
+ public IntegralDataTypeHolder initialize(long value) {
+ this.value = BigDecimal.valueOf( value );
+ return this;
+ }
+
+ public IntegralDataTypeHolder initialize(ResultSet resultSet, long defaultValue) throws SQLException {
+ final BigDecimal rsValue = resultSet.getBigDecimal( 1 );
+ if ( resultSet.wasNull() ) {
+ return initialize( defaultValue );
+ }
+ this.value = rsValue.setScale( 0, BigDecimal.ROUND_UNNECESSARY );
+ return this;
+ }
+
+ public void bind(PreparedStatement preparedStatement, int position) throws SQLException {
+ preparedStatement.setBigDecimal( position, value );
+ }
+
+ public IntegralDataTypeHolder increment() {
+ checkInitialized();
+ value = value.add( BigDecimal.ONE );
+ return this;
+ }
+
+ private void checkInitialized() {
+ if ( value == null ) {
+ throw new IdentifierGenerationException( "integral holder was not initialized" );
+ }
+ }
+
+ public IntegralDataTypeHolder add(long increment) {
+ checkInitialized();
+ value = value.add( BigDecimal.valueOf( increment ) );
+ return this;
+ }
+
+ public IntegralDataTypeHolder decrement() {
+ checkInitialized();
+ value = value.subtract( BigDecimal.ONE );
+ return this;
+ }
+
+ public IntegralDataTypeHolder subtract(long subtrahend) {
+ checkInitialized();
+ value = value.subtract( BigDecimal.valueOf( subtrahend ) );
+ return this;
+ }
+
+ public IntegralDataTypeHolder multiplyBy(IntegralDataTypeHolder factor) {
+ checkInitialized();
+ value = value.multiply( extractBigDecimal( factor ) );
+ return this;
+ }
+
+ public IntegralDataTypeHolder multiplyBy(long factor) {
+ checkInitialized();
+ value = value.multiply( BigDecimal.valueOf( factor ) );
+ return this;
+ }
+
+ public boolean eq(IntegralDataTypeHolder other) {
+ checkInitialized();
+ return value.compareTo( extractBigDecimal( other ) ) == 0;
+ }
+
+ public boolean eq(long value) {
+ checkInitialized();
+ return this.value.compareTo( BigDecimal.valueOf( value ) ) == 0;
+ }
+
+ public boolean lt(IntegralDataTypeHolder other) {
+ checkInitialized();
+ return value.compareTo( extractBigDecimal( other ) ) < 0;
+ }
+
+ public boolean lt(long value) {
+ checkInitialized();
+ return this.value.compareTo( BigDecimal.valueOf( value ) ) < 0;
+ }
+
+ public boolean gt(IntegralDataTypeHolder other) {
+ checkInitialized();
+ return value.compareTo( extractBigDecimal( other ) ) > 0;
+ }
+
+ public boolean gt(long value) {
+ checkInitialized();
+ return this.value.compareTo( BigDecimal.valueOf( value ) ) > 0;
+ }
+
+ public IntegralDataTypeHolder copy() {
+ BigDecimalHolder copy = new BigDecimalHolder();
+ copy.value = value;
+ return copy;
+ }
+
+ public Number makeValue() {
+ checkInitialized();
+ return value;
+ }
+
+ public Number makeValueThenIncrement() {
+ final Number result = makeValue();
+ value = value.add( BigDecimal.ONE );
+ return result;
+ }
+
+ public Number makeValueThenAdd(long addend) {
+ final Number result = makeValue();
+ value = value.add( BigDecimal.valueOf( addend ) );
+ return result;
+ }
+
+ public String toString() {
+ return "BigDecimalHolder[" + value + "]";
+ }
+
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+
+ BigDecimalHolder that = (BigDecimalHolder) o;
+
+ return this.value == null
+ ? that.value == null
+ : this.value.equals( that.value );
+ }
+
+ public int hashCode() {
+ return value != null ? value.hashCode() : 0;
+ }
+ }
+
/**
* Disallow instantiation of IdentifierGeneratorHelper.
*/
Modified: core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -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,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id;
@@ -53,20 +52,21 @@
* (The tables parameter specified a comma-separated list of table names.)
*
* @author Gavin King
+ * @author Steve Ebersole
*/
public class IncrementGenerator implements IdentifierGenerator, Configurable {
-
private static final Logger log = LoggerFactory.getLogger(IncrementGenerator.class);
- private long next;
+ private Class returnClass;
private String sql;
- private Class returnClass;
+ private IntegralDataTypeHolder previousValueHolder;
+
public synchronized Serializable generate(SessionImplementor session, Object object) throws HibernateException {
if ( sql != null ) {
- getNext( session );
+ initializePreviousValueHolder( session );
}
- return IdentifierGeneratorHelper.createNumber( next++, returnClass );
+ return previousValueHolder.makeValueThenIncrement();
}
public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
@@ -117,22 +117,23 @@
sql = "select max(" + column + ") from " + buf.toString();
}
- private void getNext( SessionImplementor session ) {
+ private void initializePreviousValueHolder(SessionImplementor session) {
+ previousValueHolder = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass );
+
log.debug( "fetching initial value: " + sql );
try {
- PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
+ PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
try {
ResultSet rs = st.executeQuery();
try {
if ( rs.next() ) {
- next = rs.getLong(1) + 1;
- if ( rs.wasNull() ) next = 1;
+ previousValueHolder.initialize( rs, 0L ).increment();
}
else {
- next = 1;
+ previousValueHolder.initialize( 1L );
}
- sql=null;
- log.debug("first free id: " + next);
+ sql = null;
+ log.debug( "first free id: " + previousValueHolder.makeValue() );
}
finally {
rs.close();
@@ -141,7 +142,6 @@
finally {
session.getBatcher().closeStatement(st);
}
-
}
catch (SQLException sqle) {
throw JDBCExceptionHelper.convert(
Added: core/trunk/core/src/main/java/org/hibernate/id/IntegralDataTypeHolder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IntegralDataTypeHolder.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/id/IntegralDataTypeHolder.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,206 @@
+/*
+ * 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.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Defines a common api for dealing with data of integral data type.
+ *
+ * @author Steve Ebersole
+ */
+public interface IntegralDataTypeHolder extends Serializable {
+ /**
+ * Initialize the internal value from the given primitive long.
+ *
+ * @param value The primitive integral value.
+ *
+ * @return <tt>this</tt>, for method chaining
+ */
+ public IntegralDataTypeHolder initialize(long value);
+
+ /**
+ * Initialize the internal value from the given result set, using the specified default value
+ * if we could not get a value from the result set (aka result was null).
+ *
+ * @param resultSet The JDBC result set
+ * @param defaultValue The default value to use if we did not get a result set value.
+ *
+ * @return <tt>this</tt>, for method chaining
+ *
+ * @throws SQLException Any exception from accessing the result set
+ */
+ public IntegralDataTypeHolder initialize(ResultSet resultSet, long defaultValue) throws SQLException;
+
+ /**
+ * Bind this holders internal value to the given result set.
+ *
+ * @param preparedStatement The JDBC prepared statement
+ * @param position The position at which to bind
+ *
+ * @throws SQLException Any exception from accessing the statement
+ */
+ public void bind(PreparedStatement preparedStatement, int position) throws SQLException;
+
+ /**
+ * Equivalent to a ++ operation
+ *
+ * @return <tt>this</tt>, for method chaining
+ */
+ public IntegralDataTypeHolder increment();
+
+ /**
+ * Perform an addition
+ *
+ * @param addend The value to add to this integral.
+ *
+ * @return <tt>this</tt>, for method chaining
+ */
+ public IntegralDataTypeHolder add(long addend);
+
+ /**
+ * Equivalent to a -- operation
+ *
+ * @return <tt>this</tt>, for method chaining
+ */
+ public IntegralDataTypeHolder decrement();
+
+ /**
+ * Perform a subtraction
+ *
+ * @param subtrahend The value to subtract from this integral.
+ *
+ * @return <tt>this</tt>, for method chaining
+ */
+ public IntegralDataTypeHolder subtract(long subtrahend);
+
+ /**
+ * Perform a multiplication.
+ *
+ * @param factor The factor by which to multiple this integral
+ *
+ * @return <tt>this</tt>, for method chaining
+ */
+ public IntegralDataTypeHolder multiplyBy(IntegralDataTypeHolder factor);
+
+ /**
+ * Perform a multiplication.
+ *
+ * @param factor The factor by which to multiple this integral
+ *
+ * @return <tt>this</tt>, for method chaining
+ */
+ public IntegralDataTypeHolder multiplyBy(long factor);
+
+ /**
+ * Perform an equality comparison check
+ *
+ * @param other The other value to check against our internal state
+ *
+ * @return True if the two are equal
+ */
+ public boolean eq(IntegralDataTypeHolder other);
+
+ /**
+ * Perform an equality comparison check
+ *
+ * @param other The other value to check against our internal state
+ *
+ * @return True if the two are equal
+ */
+ public boolean eq(long other);
+
+ /**
+ * Perform a "less than" comparison check. We check to see if our value is less than
+ * the incoming value...
+ *
+ * @param other The other value to check against our internal state
+ *
+ * @return True if our value is less than the 'other' value.
+ */
+ public boolean lt(IntegralDataTypeHolder other);
+
+ /**
+ * Perform a "less than" comparison check. We check to see if our value is less than
+ * the incoming value...
+ *
+ * @param other The other value to check against our internal state
+ *
+ * @return True if our value is less than the 'other' value.
+ */
+ public boolean lt(long other);
+
+ /**
+ * Perform a "greater than" comparison check. We check to see if our value is greater
+ * than the incoming value...
+ *
+ * @param other The other value to check against our internal state
+ *
+ * @return True if our value is greater than the 'other' value.
+ */
+ public boolean gt(IntegralDataTypeHolder other);
+
+ /**
+ * Perform a "greater than" comparison check. We check to see if our value is greater
+ * than the incoming value...
+ *
+ * @param other The other value to check against our internal state
+ *
+ * @return True if our value is greater than the 'other' value.
+ */
+ public boolean gt(long other);
+
+ /**
+ * Make a copy of this holder.
+ *
+ * @return The copy.
+ */
+ public IntegralDataTypeHolder copy();
+
+ /**
+ * Return the internal value.
+ *
+ * @return The current internal value
+ */
+ public Number makeValue();
+
+ /**
+ * Increment the internal state, but return the pre-incremented value.
+ *
+ * @return The pre-incremented internal value
+ */
+ public Number makeValueThenIncrement();
+
+ /**
+ * Increment the internal state by the given addend, but return the pre-incremented value.
+ *
+ * @param addend The value to be added to our internal state
+ *
+ * @return The pre-incremented internal value
+ */
+ public Number makeValueThenAdd(long addend);
+}
Modified: core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -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,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id;
@@ -104,9 +103,10 @@
//hilo params
public static final String MAX_LO = "max_lo";
- private long hi;
+ private int maxLo;
private int lo;
- private int maxLo;
+ private IntegralDataTypeHolder value;
+
private Class returnClass;
private int keySize;
@@ -146,7 +146,7 @@
}
public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
- int result;
+ IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass );
int rows;
do {
// The loop ensures atomicity of the
@@ -158,18 +158,16 @@
PreparedStatement qps = conn.prepareStatement(query);
PreparedStatement ips = null;
try {
- //qps.setString(1, key);
ResultSet rs = qps.executeQuery();
boolean isInitialized = rs.next();
if ( !isInitialized ) {
- result = 0;
- ips = conn.prepareStatement(insert);
- //ips.setString(1, key);
- ips.setInt(1, result);
+ value.initialize( 0 );
+ ips = conn.prepareStatement( insert );
+ value.bind( ips, 1 );
ips.execute();
}
else {
- result = rs.getInt(1);
+ value.initialize( rs, 0 );
}
rs.close();
}
@@ -184,12 +182,10 @@
qps.close();
}
- //sql = update;
PreparedStatement ups = conn.prepareStatement(update);
try {
- ups.setInt( 1, result + 1 );
- ups.setInt( 2, result );
- //ups.setString( 3, key );
+ value.copy().increment().bind( ups, 1 );
+ value.bind( ups, 2 );
rows = ups.executeUpdate();
}
catch (SQLException sqle) {
@@ -201,24 +197,30 @@
}
}
while (rows==0);
- return new Integer(result);
+ return value;
}
public synchronized Serializable generate(SessionImplementor session, Object obj)
throws HibernateException {
- if (maxLo < 1) {
+ // maxLo < 1 indicates a hilo generator with no hilo :?
+ if ( maxLo < 1 ) {
//keep the behavior consistent even for boundary usages
- int val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
- if (val == 0) val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
- return IdentifierGeneratorHelper.createNumber( val, returnClass );
+ IntegralDataTypeHolder value = null;
+ while ( value == null || value.lt( 1 ) ) {
+ value = (IntegralDataTypeHolder) doWorkInNewTransaction( session );
+ }
+ return value.makeValue();
}
- if (lo>maxLo) {
- int hival = ( (Integer) doWorkInNewTransaction(session) ).intValue();
- lo = (hival == 0) ? 1 : 0;
- hi = hival * (maxLo+1);
- log.debug("new hi value: " + hival);
+
+ if ( lo > maxLo ) {
+ IntegralDataTypeHolder hiVal = (IntegralDataTypeHolder) doWorkInNewTransaction( 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 IdentifierGeneratorHelper.createNumber( hi + lo++, returnClass );
+ return value.makeValueThenIncrement();
}
public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
Modified: core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -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,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id;
@@ -98,19 +97,19 @@
sql = dialect.getSequenceNextValString( sequenceName );
}
- public Serializable generate(SessionImplementor session, Object obj)
- throws HibernateException {
-
+ public Serializable generate(SessionImplementor session, Object obj) {
+ return generateHolder( session ).makeValue();
+ }
+
+ protected IntegralDataTypeHolder generateHolder(SessionImplementor session) {
try {
-
PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
try {
ResultSet rs = st.executeQuery();
try {
rs.next();
- Serializable result = IdentifierGeneratorHelper.get(
- rs, identifierType
- );
+ IntegralDataTypeHolder result = buildHolder();
+ result.initialize( rs, 1 );
if ( log.isDebugEnabled() ) {
log.debug("Sequence identifier generated: " + result);
}
@@ -123,7 +122,7 @@
finally {
session.getBatcher().closeStatement(st);
}
-
+
}
catch (SQLException sqle) {
throw JDBCExceptionHelper.convert(
@@ -131,9 +130,12 @@
sqle,
"could not get next sequence value",
sql
- );
+ );
}
+ }
+ protected IntegralDataTypeHolder buildHolder() {
+ return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
}
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
Modified: core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -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,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.id;
@@ -29,7 +28,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
@@ -59,33 +57,36 @@
private int maxLo;
private int lo;
- private long hi;
- private Class returnClass;
+ private IntegralDataTypeHolder value;
+
public void configure(Type type, Properties params, Dialect d) throws MappingException {
super.configure(type, params, d);
maxLo = PropertiesHelper.getInt(MAX_LO, params, 9);
lo = maxLo + 1; // so we "clock over" on the first invocation
- returnClass = type.getReturnedClass();
}
- public synchronized Serializable generate(SessionImplementor session, Object obj)
- throws HibernateException {
- if (maxLo < 1) {
+ public synchronized Serializable generate(SessionImplementor session, Object obj) {
+ // maxLo < 1 indicates a hilo generator with no hilo :?
+ if ( maxLo < 1 ) {
//keep the behavior consistent even for boundary usages
- long val = ( (Number) super.generate(session, obj) ).longValue();
- if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
- return IdentifierGeneratorHelper.createNumber( val, returnClass );
+ IntegralDataTypeHolder value = null;
+ while ( value == null || value.lt( 0 ) ) {
+ value = super.generateHolder( session );
+ }
+ return value.makeValue();
}
- if ( lo>maxLo ) {
- long hival = ( (Number) super.generate(session, obj) ).longValue();
- lo = (hival == 0) ? 1 : 0;
- hi = hival * ( maxLo+1 );
- if ( log.isDebugEnabled() )
- log.debug("new hi value: " + hival);
+
+ 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 IdentifierGeneratorHelper.createNumber( hi + lo++, returnClass );
+ return value.makeValueThenIncrement();
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -50,17 +50,21 @@
* table to store the last generated value. It is not
* intended that applications use this strategy directly.
* However, it may be used to build other (efficient)
- * strategies. The returned type is <tt>Integer</tt>.<br>
- * <br>
- * The hi value MUST be fetched in a seperate 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 Hibernate is
- * fetching connections when the user is supplying
- * connections.<br>
- * <br>
- * The returned value is of type <tt>integer</tt>.<br>
- * <br>
+ * strategies. The returned type is any supported by
+ * {@link IntegralDataTypeHolder}
+ * <p/>
+ * The value MUST be fetched in a separate transaction
+ * from that of the main {@link SessionImplementor session}
+ * transaction so the generator must be able to obtain a new
+ * connection and commit it. Hence this implementation may only
+ * be used when Hibernate is fetching connections, not when the
+ * user is supplying connections.
+ * <p/>
+ * Again, the return types supported here are any of the ones
+ * supported by {@link IntegralDataTypeHolder}. This is new
+ * as of 3.5. Prior to that this generator only returned {@link Integer}
+ * values.
+ * <p/>
* Mapping parameters supported: table, column
*
* @see TableHiLoGenerator
@@ -83,12 +87,15 @@
private static final Logger log = LoggerFactory.getLogger(TableGenerator.class);
+ private Type identifierType;
private String tableName;
private String columnName;
private String query;
private String update;
public void configure(Type type, Properties params, Dialect dialect) {
+ identifierType = type;
+
ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
tableName = PropertiesHelper.getString( TABLE, params, DEFAULT_TABLE_NAME );
@@ -127,12 +134,13 @@
" = ?";
}
- public synchronized Serializable generate(SessionImplementor session, Object object)
- throws HibernateException {
- int result = ( (Integer) doWorkInNewTransaction(session) ).intValue();
- return new Integer(result);
+ public synchronized Serializable generate(SessionImplementor session, Object object) {
+ return generateHolder( session ).makeValue();
}
+ protected IntegralDataTypeHolder generateHolder(SessionImplementor session) {
+ return (IntegralDataTypeHolder) doWorkInNewTransaction( session );
+ }
public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
return new String[] {
@@ -157,8 +165,19 @@
return tableName;
}
+ /**
+ * Get the next value.
+ *
+ * @param conn The sql connection to use.
+ * @param sql n/a
+ *
+ * @return Prior to 3.5 this method returned an {@link Integer}. Since 3.5 it now
+ * returns a {@link IntegralDataTypeHolder}
+ *
+ * @throws SQLException
+ */
public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
- int result;
+ IntegralDataTypeHolder value = buildHolder();
int rows;
do {
// The loop ensures atomicity of the
@@ -175,7 +194,7 @@
log.error(err);
throw new IdentifierGenerationException(err);
}
- result = rs.getInt(1);
+ value.initialize( rs, 1 );
rs.close();
}
catch (SQLException sqle) {
@@ -190,8 +209,8 @@
SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
PreparedStatement ups = conn.prepareStatement(update);
try {
- ups.setInt( 1, result + 1 );
- ups.setInt( 2, result );
+ value.copy().increment().bind( ups, 1 );
+ value.bind( ups, 2 );
rows = ups.executeUpdate();
}
catch (SQLException sqle) {
@@ -203,6 +222,10 @@
}
}
while (rows==0);
- return new Integer(result);
+ return value;
}
+
+ protected IntegralDataTypeHolder buildHolder() {
+ return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
+ }
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -29,7 +29,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.type.Type;
@@ -58,37 +57,40 @@
*/
public static final String MAX_LO = "max_lo";
- private long hi;
+ private int maxLo;
private int lo;
- private int maxLo;
- private Class returnClass;
+ 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
- returnClass = type.getReturnedClass();
}
- public synchronized Serializable generate(SessionImplementor session, Object obj)
- throws HibernateException {
- if (maxLo < 1) {
+ public synchronized Serializable generate(SessionImplementor session, Object obj) {
+ // maxLo < 1 indicates a hilo generator with no hilo :?
+ if ( maxLo < 1 ) {
//keep the behavior consistent even for boundary usages
- long val = ( (Number) super.generate(session, obj) ).longValue();
- if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
- return IdentifierGeneratorHelper.createNumber( val, returnClass );
+ IntegralDataTypeHolder value = null;
+ while ( value == null || value.lt( 0 ) ) {
+ value = generateHolder( session );
+ }
+ return value.makeValue();
}
- if (lo>maxLo) {
- long hival = ( (Number) super.generate(session, obj) ).longValue();
- lo = (hival == 0) ? 1 : 0;
- hi = hival * (maxLo+1);
- log.debug("new hi value: " + hival);
+
+ 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 IdentifierGeneratorHelper.createNumber( hi + lo++, returnClass );
-
+ return value.makeValueThenIncrement();
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -24,6 +24,8 @@
*/
package org.hibernate.id.enhanced;
+import org.hibernate.id.IntegralDataTypeHolder;
+
/**
* Contract for providing callback access to a {@link DatabaseStructure},
* typically from the {@link Optimizer}.
@@ -36,5 +38,5 @@
*
* @return The next value.
*/
- public long getNextValue();
+ public IntegralDataTypeHolder getNextValue();
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -26,6 +26,8 @@
import java.io.Serializable;
+import org.hibernate.id.IntegralDataTypeHolder;
+
/**
* Performs optimization on an optimizable identifier generator. Typically
* this optimization takes the form of trying to ensure we do not have to
@@ -51,12 +53,12 @@
/**
* A common means to access the last value obtained from the underlying
* source. This is intended for testing purposes, since accessing the
- * unerlying database source directly is much more difficult.
+ * underlying database source directly is much more difficult.
*
* @return The last value we obtained from the underlying source;
- * -1 indicates we have not yet consulted with the source.
+ * null indicates we have not yet consulted with the source.
*/
- public long getLastSourceValue();
+ public IntegralDataTypeHolder getLastSourceValue();
/**
* Retrieves the defined increment size.
Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -31,8 +31,8 @@
import org.slf4j.LoggerFactory;
import org.hibernate.HibernateException;
+import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.util.ReflectHelper;
-import org.hibernate.id.IdentifierGeneratorHelper;
/**
* Factory for {@link Optimizer} instances.
@@ -98,17 +98,6 @@
}
/**
- * Take the primitive long value and "make" (or wrap) it into the
- * {@link #getReturnClass id type}.
- *
- * @param value The primitive value to make/wrap.
- * @return The wrapped value.
- */
- protected final Serializable make(long value) {
- return IdentifierGeneratorHelper.createNumber( value, returnClass );
- }
-
- /**
* Getter for property 'returnClass'. This is the Java
* class which is used to represent the id (e.g. {@link java.lang.Long}).
*
@@ -131,7 +120,7 @@
* every request.
*/
public static class NoopOptimizer extends OptimizerSupport {
- private long lastSourceValue = -1;
+ private IntegralDataTypeHolder lastSourceValue;
public NoopOptimizer(Class returnClass, int incrementSize) {
super( returnClass, incrementSize );
@@ -141,21 +130,21 @@
* {@inheritDoc}
*/
public Serializable generate(AccessCallback callback) {
- if ( lastSourceValue == -1 ) {
- while( lastSourceValue <= 0 ) {
+ if ( lastSourceValue == null ) {
+ do {
lastSourceValue = callback.getNextValue();
- }
+ } while ( lastSourceValue.lt( 1 ) );
}
else {
lastSourceValue = callback.getNextValue();
}
- return make( lastSourceValue );
+ return lastSourceValue.makeValue();
}
/**
* {@inheritDoc}
*/
- public long getLastSourceValue() {
+ public IntegralDataTypeHolder getLastSourceValue() {
return lastSourceValue;
}
@@ -170,11 +159,40 @@
/**
* Optimizer which applies a 'hilo' algorithm in memory to achieve
* optimization.
+ * <p/>
+ * A 'hilo' algorithm is simply a means for a single value stored in the
+ * database to represent a "bucket" of possible, contiguous values. The
+ * database value identifies which particular bucket we are on.
+ * <p/>
+ * This database value must be paired with another value that defines the
+ * size of the bucket; the number of possible values available.
+ * The {@link #getIncrementSize() incrementSize} serves this purpose. The
+ * naming here is meant more for consistency in that this value serves the
+ * same purpose as the increment supplied to the {@link PooledOptimizer}.
+ * <p/>
+ * The general algorithms used to determine the bucket are:<ol>
+ * <li>{@code upperLimit = (databaseValue * incrementSize) + 1}</li>
+ * <li>{@code lowerLimit = upperLimit - 1}</li>
+ * </ol>
+ * As an example, consider a case with incrementSize of 10. Initially the
+ * database holds 1:<ol>
+ * <li>{@code upperLimit = (1 * 20) + 1 = 21}</li>
+ * <li>{@code lowerLimit = 21 - 20 = 1}</li>
+ * </ol>
+ * From there we increment the value from lowerLimit until we reach the
+ * upperLimit, at which point we would define a new bucket. The database
+ * now contains 2, though incrementSize remains unchanged:<ol>
+ * <li>{@code upperLimit = (2 * 20) + 1 = 41}</li>
+ * <li>{@code lowerLimit = 41 - 20 = 21}</li>
+ * </ol>
+ * And so on...
+ * <p/>
+ * Note, 'value' always (after init) holds the next value to return
*/
public static class HiLoOptimizer extends OptimizerSupport {
- private long lastSourceValue = -1;
- private long value;
- private long hiValue;
+ private IntegralDataTypeHolder lastSourceValue;
+ private IntegralDataTypeHolder upperLimit;
+ private IntegralDataTypeHolder value;
public HiLoOptimizer(Class returnClass, int incrementSize) {
super( returnClass, incrementSize );
@@ -190,26 +208,30 @@
* {@inheritDoc}
*/
public synchronized Serializable generate(AccessCallback callback) {
- if ( lastSourceValue < 0 ) {
+ if ( lastSourceValue == null ) {
+ // first call, so initialize ourselves. we need to read the database
+ // value and set up the 'bucket' boundaries
lastSourceValue = callback.getNextValue();
- while ( lastSourceValue <= 0 ) {
+ while ( lastSourceValue.lt( 1 ) ) {
lastSourceValue = callback.getNextValue();
}
- hiValue = ( lastSourceValue * incrementSize ) + 1;
- value = hiValue - incrementSize;
+ // upperLimit defines the upper end of the bucket values
+ upperLimit = lastSourceValue.copy().multiplyBy( incrementSize ).increment();
+ // initialize value to the low end of the bucket
+ value = upperLimit.copy().subtract( incrementSize );
}
- else if ( value >= hiValue ) {
+ else if ( ! upperLimit.gt( value ) ) {
lastSourceValue = callback.getNextValue();
- hiValue = ( lastSourceValue * incrementSize ) + 1;
+ upperLimit = lastSourceValue.copy().multiplyBy( incrementSize ).increment();
}
- return make( value++ );
+ return value.makeValueThenIncrement();
}
/**
* {@inheritDoc}
*/
- public long getLastSourceValue() {
+ public IntegralDataTypeHolder getLastSourceValue() {
return lastSourceValue;
}
@@ -222,30 +244,38 @@
/**
* Getter for property 'lastValue'.
+ * <p/>
+ * Exposure intended for testing purposes.
*
* @return Value for property 'lastValue'.
*/
- public long getLastValue() {
- return value - 1;
+ public IntegralDataTypeHolder getLastValue() {
+ return value.copy().decrement();
}
/**
- * Getter for property 'hiValue'.
+ * Getter for property 'upperLimit'.
+ * <p/>
+ * Exposure intended for testing purposes.
*
- * @return Value for property 'hiValue'.
+ * @return Value for property 'upperLimit'.
*/
- public long getHiValue() {
- return hiValue;
+ public IntegralDataTypeHolder getHiValue() {
+ return upperLimit;
}
}
/**
* Optimizer which uses a pool of values, storing the next low value of the
* range in the database.
+ * <p/>
+ * Note that this optimizer works essentially the same as the
+ * {@link HiLoOptimizer} except that here the bucket ranges are actually
+ * encoded into the database structures.
*/
public static class PooledOptimizer extends OptimizerSupport {
- private long value;
- private long hiValue = -1;
+ private IntegralDataTypeHolder hiValue;
+ private IntegralDataTypeHolder value;
public PooledOptimizer(Class returnClass, int incrementSize) {
super( returnClass, incrementSize );
@@ -261,9 +291,9 @@
* {@inheritDoc}
*/
public synchronized Serializable generate(AccessCallback callback) {
- if ( hiValue < 0 ) {
+ if ( hiValue == null ) {
value = callback.getNextValue();
- if ( value < 1 ) {
+ if ( value.lt( 1 ) ) {
// unfortunately not really safe to normalize this
// to 1 as an initial value like we do the others
// because we would not be able to control this if
@@ -272,17 +302,17 @@
}
hiValue = callback.getNextValue();
}
- else if ( value >= hiValue ) {
+ else if ( ! hiValue.gt( value ) ) {
hiValue = callback.getNextValue();
- value = hiValue - incrementSize;
+ value = hiValue.copy().subtract( incrementSize );
}
- return make( value++ );
+ return value.makeValueThenIncrement();
}
/**
* {@inheritDoc}
*/
- public long getLastSourceValue() {
+ public IntegralDataTypeHolder getLastSourceValue() {
return hiValue;
}
@@ -295,11 +325,13 @@
/**
* Getter for property 'lastValue'.
+ * <p/>
+ * Exposure intended for testing purposes.
*
* @return Value for property 'lastValue'.
*/
- public long getLastValue() {
- return value - 1;
+ public IntegralDataTypeHolder getLastValue() {
+ return value.copy().decrement();
}
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -35,6 +35,8 @@
import org.hibernate.engine.SessionImplementor;
import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.HibernateException;
+import org.hibernate.id.IdentifierGeneratorHelper;
+import org.hibernate.id.IntegralDataTypeHolder;
/**
* Describes a sequence.
@@ -47,14 +49,21 @@
private final String sequenceName;
private final int initialValue;
private final int incrementSize;
+ private final Class numberType;
private final String sql;
private boolean applyIncrementSizeToSourceValues;
private int accessCounter;
- public SequenceStructure(Dialect dialect, String sequenceName, int initialValue, int incrementSize) {
+ public SequenceStructure(
+ Dialect dialect,
+ String sequenceName,
+ int initialValue,
+ int incrementSize,
+ Class numberType) {
this.sequenceName = sequenceName;
this.initialValue = initialValue;
this.incrementSize = incrementSize;
+ this.numberType = numberType;
sql = dialect.getSequenceNextValString( sequenceName );
}
@@ -91,7 +100,7 @@
*/
public AccessCallback buildCallback(final SessionImplementor session) {
return new AccessCallback() {
- public long getNextValue() {
+ public IntegralDataTypeHolder getNextValue() {
accessCounter++;
try {
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
@@ -99,11 +108,12 @@
ResultSet rs = st.executeQuery();
try {
rs.next();
- long result = rs.getLong( 1 );
+ IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType );
+ value.initialize( rs, 1 );
if ( log.isDebugEnabled() ) {
- log.debug("Sequence identifier generated: " + result);
+ log.debug( "Sequence value obtained: " + value.makeValue() );
}
- return result;
+ return value;
}
finally {
try {
Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -178,7 +178,15 @@
}
}
- this.databaseStructure = buildDatabaseStructure( params, dialect, forceTableUse, sequenceName, initialValue, incrementSize );
+ this.databaseStructure = buildDatabaseStructure(
+ type,
+ params,
+ dialect,
+ forceTableUse,
+ sequenceName,
+ initialValue,
+ incrementSize
+ );
this.optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
this.databaseStructure.prepare( optimizer );
@@ -291,15 +299,16 @@
/**
* Build the database structure.
*
+ * @param type The Hibernate type of the identifier property
* @param params The params supplied in the generator config (plus some standard useful extras).
* @param dialect The dialect being used.
* @param forceTableUse Should a table be used even if the dialect supports sequences?
* @param sequenceName The name to use for the sequence or table.
* @param initialValue The initial value.
- * @param incrementSize the increment size to use (after any adjustments).
- * @return The db structure representation
+ * @param incrementSize the increment size to use (after any adjustments). @return The db structure representation
*/
protected DatabaseStructure buildDatabaseStructure(
+ Type type,
Properties params,
Dialect dialect,
boolean forceTableUse,
@@ -308,11 +317,11 @@
int incrementSize) {
boolean useSequence = dialect.supportsSequences() && !forceTableUse;
if ( useSequence ) {
- return new SequenceStructure( dialect, sequenceName, initialValue, incrementSize );
+ return new SequenceStructure( dialect, sequenceName, initialValue, incrementSize, type.getReturnedClass() );
}
else {
String valueColumnName = determineValueColumnName( params, dialect );
- return new TableStructure( dialect, sequenceName, valueColumnName, initialValue, incrementSize );
+ return new TableStructure( dialect, sequenceName, valueColumnName, initialValue, incrementSize, type.getReturnedClass() );
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -39,6 +39,8 @@
import org.hibernate.engine.TransactionHelper;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.IdentifierGeneratorHelper;
+import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.Configurable;
import org.hibernate.type.Type;
@@ -287,7 +289,7 @@
public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
identifierType = type;
- tableName = determneGeneratorTableName( params, dialect );
+ tableName = determineGeneratorTableName( params, dialect );
segmentColumnName = determineSegmentColumnName( params, dialect );
valueColumnName = determineValueColumnName( params, dialect );
@@ -316,7 +318,7 @@
* @param dialect The dialect in effect
* @return The table name to use.
*/
- protected String determneGeneratorTableName(Properties params, Dialect dialect) {
+ protected String determineGeneratorTableName(Properties params, Dialect dialect) {
String name = PropertiesHelper.getString( TABLE_PARAM, params, DEF_TABLE );
boolean isGivenNameUnqualified = name.indexOf( '.' ) < 0;
if ( isGivenNameUnqualified ) {
@@ -450,8 +452,8 @@
public synchronized Serializable generate(final SessionImplementor session, Object obj) {
return optimizer.generate(
new AccessCallback() {
- public long getNextValue() {
- return ( ( Number ) doWorkInNewTransaction( session ) ).longValue();
+ public IntegralDataTypeHolder getNextValue() {
+ return ( IntegralDataTypeHolder ) doWorkInNewTransaction( session );
}
}
);
@@ -461,7 +463,7 @@
* {@inheritDoc}
*/
public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
- int result;
+ IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() );
int rows;
do {
SQL_STATEMENT_LOGGER.logStatement( selectQuery, FormatStyle.BASIC );
@@ -470,13 +472,13 @@
selectPS.setString( 1, segmentValue );
ResultSet selectRS = selectPS.executeQuery();
if ( !selectRS.next() ) {
+ value.initialize( initialValue );
PreparedStatement insertPS = null;
try {
- result = initialValue;
SQL_STATEMENT_LOGGER.logStatement( insertQuery, FormatStyle.BASIC );
insertPS = conn.prepareStatement( insertQuery );
insertPS.setString( 1, segmentValue );
- insertPS.setLong( 2, result );
+ value.bind( insertPS, 2 );
insertPS.execute();
}
finally {
@@ -486,7 +488,7 @@
}
}
else {
- result = selectRS.getInt( 1 );
+ value.initialize( selectRS, 1 );
}
selectRS.close();
}
@@ -501,10 +503,15 @@
SQL_STATEMENT_LOGGER.logStatement( updateQuery, FormatStyle.BASIC );
PreparedStatement updatePS = conn.prepareStatement( updateQuery );
try {
- long newValue = optimizer.applyIncrementSizeToSourceValues()
- ? result + incrementSize : result + 1;
- updatePS.setLong( 1, newValue );
- updatePS.setLong( 2, result );
+ final IntegralDataTypeHolder updateValue = value.copy();
+ if ( optimizer.applyIncrementSizeToSourceValues() ) {
+ updateValue.add( incrementSize );
+ }
+ else {
+ updateValue.increment();
+ }
+ updateValue.bind( updatePS, 1 );
+ value.bind( updatePS, 2 );
updatePS.setString( 3, segmentValue );
rows = updatePS.executeUpdate();
}
@@ -520,7 +527,7 @@
accessCount++;
- return new Integer( result );
+ return value;
}
/**
Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -40,6 +40,8 @@
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.TransactionHelper;
import org.hibernate.id.IdentifierGenerationException;
+import org.hibernate.id.IdentifierGeneratorHelper;
+import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.jdbc.util.FormatStyle;
import org.hibernate.jdbc.util.SQLStatementLogger;
@@ -56,17 +58,25 @@
private final String valueColumnName;
private final int initialValue;
private final int incrementSize;
+ private final Class numberType;
private final String selectQuery;
private final String updateQuery;
private boolean applyIncrementSizeToSourceValues;
private int accessCounter;
- public TableStructure(Dialect dialect, String tableName, String valueColumnName, int initialValue, int incrementSize) {
+ public TableStructure(
+ Dialect dialect,
+ String tableName,
+ String valueColumnName,
+ int initialValue,
+ int incrementSize,
+ Class numberType) {
this.tableName = tableName;
this.initialValue = initialValue;
this.incrementSize = incrementSize;
this.valueColumnName = valueColumnName;
+ this.numberType = numberType;
selectQuery = "select " + valueColumnName + " as id_val" +
" from " + dialect.appendLockHint( LockMode.PESSIMISTIC_WRITE, tableName ) +
@@ -117,8 +127,8 @@
*/
public AccessCallback buildCallback(final SessionImplementor session) {
return new AccessCallback() {
- public long getNextValue() {
- return ( ( Number ) doWorkInNewTransaction( session ) ).longValue();
+ public IntegralDataTypeHolder getNextValue() {
+ return ( IntegralDataTypeHolder ) doWorkInNewTransaction( session );
}
};
}
@@ -152,7 +162,7 @@
* {@inheritDoc}
*/
protected Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
- long result;
+ IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType );
int rows;
do {
SQL_STATEMENT_LOGGER.logStatement( selectQuery, FormatStyle.BASIC );
@@ -164,7 +174,7 @@
log.error( err );
throw new IdentifierGenerationException( err );
}
- result = selectRS.getLong( 1 );
+ value.initialize( selectRS, 1 );
selectRS.close();
}
catch ( SQLException sqle ) {
@@ -178,9 +188,10 @@
SQL_STATEMENT_LOGGER.logStatement( updateQuery, FormatStyle.BASIC );
PreparedStatement updatePS = conn.prepareStatement( updateQuery );
try {
- int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;
- updatePS.setLong( 1, result + increment );
- updatePS.setLong( 2, result );
+ final int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;
+ final IntegralDataTypeHolder updateValue = value.copy().add( increment );
+ updateValue.bind( updatePS, 1 );
+ value.bind( updatePS, 2 );
rows = updatePS.executeUpdate();
}
catch ( SQLException sqle ) {
@@ -194,7 +205,7 @@
accessCounter++;
- return new Long( result );
+ return value;
}
}
Added: core/trunk/core/src/test/java/org/hibernate/id/AbstractHolderTest.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/id/AbstractHolderTest.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/id/AbstractHolderTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,167 @@
+/*
+ * 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 junit.framework.TestCase;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractHolderTest extends TestCase {
+ protected abstract IntegralDataTypeHolder makeHolder();
+
+ public void testInitializationChecking() {
+ IntegralDataTypeHolder holder = makeHolder();
+ try {
+ holder.increment();
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.add( 1 );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.decrement();
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.subtract( 1 );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.multiplyBy( holder );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.multiplyBy( 1 );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.eq( holder );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.eq( 1 );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.lt( holder );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.lt( 1 );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.gt( holder );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.gt( 1 );
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+
+ try {
+ holder.makeValue();
+ fail();
+ }
+ catch ( IdentifierGenerationException expected ) {
+ }
+ }
+
+ public void testIncrement() {
+ IntegralDataTypeHolder holder = makeHolder();
+ holder.initialize( 0 );
+ int i = 0;
+ for ( ; i < 5008; i++ ) {
+ holder.increment();
+ }
+ assertEquals( holder.copy().initialize( i ), holder );
+ }
+
+ public void testBasicHiloAlgorithm() {
+ // mimic an initialValue of 1 and increment of 20
+ final long initialValue = 1;
+ final long incrementSize = 2;
+
+ // initialization
+ IntegralDataTypeHolder lastSourceValue = makeHolder().initialize( 1 );
+ IntegralDataTypeHolder upperLimit = lastSourceValue.copy().multiplyBy( incrementSize ).increment();
+ IntegralDataTypeHolder value = upperLimit.copy().subtract( incrementSize );
+
+ assertEquals( 1, lastSourceValue.makeValue().longValue() );
+ assertEquals( 3, upperLimit.makeValue().longValue() );
+ assertEquals( 1, value.makeValue().longValue() );
+
+ value.increment();
+ value.increment();
+
+ assertFalse( upperLimit.gt( value ) );
+
+ // at which point we would "clock over"
+ lastSourceValue.increment();
+ upperLimit = lastSourceValue.copy().multiplyBy( incrementSize ).increment();
+
+ assertEquals( 2, lastSourceValue.makeValue().longValue() );
+ assertEquals( 5, upperLimit.makeValue().longValue() );
+ assertEquals( 3, value.makeValue().longValue() );
+ }
+}
Added: core/trunk/core/src/test/java/org/hibernate/id/BigDecimalHolderTest.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/id/BigDecimalHolderTest.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/id/BigDecimalHolderTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,37 @@
+/*
+ * 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.math.BigDecimal;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class BigDecimalHolderTest extends AbstractHolderTest {
+ protected IntegralDataTypeHolder makeHolder() {
+ return IdentifierGeneratorHelper.getIntegralDataTypeHolder( BigDecimal.class );
+ }
+}
\ No newline at end of file
Added: core/trunk/core/src/test/java/org/hibernate/id/BigIntegerHolderTest.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/id/BigIntegerHolderTest.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/id/BigIntegerHolderTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,37 @@
+/*
+ * 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.math.BigInteger;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class BigIntegerHolderTest extends AbstractHolderTest {
+ protected IntegralDataTypeHolder makeHolder() {
+ return IdentifierGeneratorHelper.getIntegralDataTypeHolder( BigInteger.class );
+ }
+}
Added: core/trunk/core/src/test/java/org/hibernate/id/LongHolderTest.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/id/LongHolderTest.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/id/LongHolderTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class LongHolderTest extends AbstractHolderTest {
+ protected IntegralDataTypeHolder makeHolder() {
+ return IdentifierGeneratorHelper.getIntegralDataTypeHolder( Long.class );
+ }
+}
Copied: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/BigIntegerIncrementGeneratorTest.java (from rev 18771, core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/BasicForcedTableSequenceTest.java)
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/BigIntegerIncrementGeneratorTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/BigIntegerIncrementGeneratorTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,73 @@
+/*
+ * 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.test.idgen.biginteger.increment;
+
+import java.math.BigInteger;
+
+import junit.framework.Test;
+
+import org.hibernate.Session;
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class BigIntegerIncrementGeneratorTest extends FunctionalTestCase {
+ public BigIntegerIncrementGeneratorTest(String string) {
+ super( string );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "idgen/biginteger/increment/Mapping.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( BigIntegerIncrementGeneratorTest.class );
+ }
+
+ public void testBasics() {
+ Session s = openSession();
+ s.beginTransaction();
+ Entity entity = new Entity( "BigInteger + increment #1" );
+ s.save( entity );
+ Entity entity2 = new Entity( "BigInteger + increment #2" );
+ s.save( entity2 );
+ s.getTransaction().commit();
+ s.close();
+
+ assertEquals( BigInteger.valueOf( 1 ), entity.getId() );
+ assertEquals( BigInteger.valueOf( 2 ), entity2.getId() );
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( entity );
+ s.delete( entity2 );
+ s.getTransaction().commit();
+ s.close();
+
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/Entity.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/Entity.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/Entity.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,59 @@
+/*
+ * 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.test.idgen.biginteger.increment;
+
+import java.math.BigInteger;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class Entity {
+ private BigInteger id;
+ private String name;
+
+ public Entity() {
+ }
+
+ public Entity(String name) {
+ this.name = name;
+ }
+
+ public BigInteger getId() {
+ return id;
+ }
+
+ public void setId(BigInteger id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Copied: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/Mapping.hbm.xml (from rev 18771, core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/Basic.hbm.xml)
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/Mapping.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/increment/Mapping.hbm.xml 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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
+ -->
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+ Demonstrates use of simple increment generator on a BigInteger property.
+-->
+
+<hibernate-mapping package="org.hibernate.test.idgen.biginteger.increment">
+
+ <class name="Entity">
+ <id name="id" column="ID" type="big_integer">
+ <generator class="increment" />
+ </id>
+ <property name="name" type="string"/>
+ </class>
+
+</hibernate-mapping>
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/BigIntegerSequenceGeneratorTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/BigIntegerSequenceGeneratorTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/BigIntegerSequenceGeneratorTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,79 @@
+/*
+ * 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.test.idgen.biginteger.sequence;
+
+import junit.framework.Test;
+
+import org.hibernate.Session;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class BigIntegerSequenceGeneratorTest extends DatabaseSpecificFunctionalTestCase {
+ public BigIntegerSequenceGeneratorTest(String string) {
+ super( string );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "idgen/biginteger/sequence/Mapping.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( BigIntegerSequenceGeneratorTest.class );
+ }
+
+ @Override
+ public boolean appliesTo(Dialect dialect) {
+ return dialect.supportsSequences();
+ }
+
+ public void testBasics() {
+ Session s = openSession();
+ s.beginTransaction();
+ Entity entity = new Entity( "BigInteger + sequence #1" );
+ s.save( entity );
+ Entity entity2 = new Entity( "BigInteger + sequence #2" );
+ s.save( entity2 );
+ s.getTransaction().commit();
+ s.close();
+
+// hsqldb defines different behavior for the initial select from a sequence
+// then say oracle
+// assertEquals( BigInteger.valueOf( 1 ), entity.getId() );
+// assertEquals( BigInteger.valueOf( 2 ), entity2.getId() );
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( entity );
+ s.delete( entity2 );
+ s.getTransaction().commit();
+ s.close();
+
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/Entity.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/Entity.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/Entity.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,59 @@
+/*
+ * 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.test.idgen.biginteger.sequence;
+
+import java.math.BigInteger;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class Entity {
+ private BigInteger id;
+ private String name;
+
+ public Entity() {
+ }
+
+ public Entity(String name) {
+ this.name = name;
+ }
+
+ public BigInteger getId() {
+ return id;
+ }
+
+ public void setId(BigInteger id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/Mapping.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/Mapping.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/biginteger/sequence/Mapping.hbm.xml 2010-02-12 06:22:52 UTC (rev 18789)
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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
+ -->
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+ Demonstrates use of a sequence generator on a BigInteger property.
+-->
+
+<hibernate-mapping package="org.hibernate.test.idgen.biginteger.sequence">
+
+ <class name="Entity">
+ <id name="id" column="ID" type="big_integer">
+ <generator class="sequence">
+ </generator>
+ </id>
+ <property name="name" type="string"/>
+ </class>
+
+</hibernate-mapping>
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -3,6 +3,8 @@
import junit.framework.Test;
import junit.framework.TestSuite;
+import org.hibernate.id.IdentifierGeneratorHelper;
+import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.junit.UnitTestCase;
import org.hibernate.id.enhanced.Optimizer;
import org.hibernate.id.enhanced.OptimizerFactory;
@@ -88,7 +90,7 @@
next = ( Long ) optimizer.generate( sequence );
assertEquals( i, next.intValue() );
}
- assertEquals( 2, sequence.getTimesCalled() ); // twice to initialze state
+ assertEquals( 2, sequence.getTimesCalled() ); // twice to initialize state
assertEquals( 11, sequence.getCurrentValue() );
// force a "clock over"
next = ( Long ) optimizer.generate( sequence );
@@ -98,7 +100,7 @@
}
private static class SourceMock implements AccessCallback {
- private long value;
+ private IdentifierGeneratorHelper.BasicHolder value = new IdentifierGeneratorHelper.BasicHolder( Long.class );
private int increment;
private int timesCalled = 0;
@@ -108,12 +110,12 @@
public SourceMock(long initialValue, int increment) {
this.increment = increment;
- this.value = initialValue - increment;
+ this.value.initialize( initialValue - increment );
}
- public long getNextValue() {
+ public IntegralDataTypeHolder getNextValue() {
timesCalled++;
- return ( value += increment );
+ return value.add( increment ).copy();
}
public int getTimesCalled() {
@@ -121,7 +123,7 @@
}
public long getCurrentValue() {
- return value;
+ return value.getActualLongValue();
}
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/BasicForcedTableSequenceTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/BasicForcedTableSequenceTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/BasicForcedTableSequenceTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -2,14 +2,16 @@
import junit.framework.Test;
+import org.hibernate.Session;
+import org.hibernate.id.enhanced.OptimizerFactory;
+import org.hibernate.id.enhanced.SequenceStyleGenerator;
+import org.hibernate.id.enhanced.TableStructure;
import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.id.enhanced.SequenceStyleGenerator;
-import org.hibernate.id.enhanced.TableStructure;
-import org.hibernate.id.enhanced.OptimizerFactory;
-import org.hibernate.Session;
+import static org.hibernate.id.IdentifierGeneratorHelper.BasicHolder;
+
/**
* {@inheritDoc}
*
@@ -54,7 +56,7 @@
long expectedId = i + 1;
assertEquals( expectedId, entities[i].getId().longValue() );
assertEquals( expectedId, generator.getDatabaseStructure().getTimesAccessed() );
- assertEquals( expectedId, generator.getOptimizer().getLastSourceValue() );
+ assertEquals( expectedId, ( (BasicHolder) generator.getOptimizer().getLastSourceValue() ).getActualLongValue() );
}
s.getTransaction().commit();
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/HiLoForcedTableSequenceTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/HiLoForcedTableSequenceTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/HiLoForcedTableSequenceTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -2,14 +2,16 @@
import junit.framework.Test;
+import org.hibernate.Session;
+import org.hibernate.id.enhanced.OptimizerFactory;
+import org.hibernate.id.enhanced.SequenceStyleGenerator;
+import org.hibernate.id.enhanced.TableStructure;
import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.id.enhanced.OptimizerFactory;
-import org.hibernate.id.enhanced.SequenceStyleGenerator;
-import org.hibernate.id.enhanced.TableStructure;
-import org.hibernate.Session;
+import static org.hibernate.id.IdentifierGeneratorHelper.BasicHolder;
+
/**
* {@inheritDoc}
*
@@ -54,18 +56,18 @@
s.save( entities[i] );
long expectedId = i + 1;
assertEquals( expectedId, entities[i].getId().longValue() );
- assertEquals( 1, generator.getOptimizer().getLastSourceValue() );
- assertEquals( i + 1, optimizer.getLastValue() );
- assertEquals( increment + 1, optimizer.getHiValue() );
+ assertEquals( 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() );
+ assertEquals( i + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getHiValue() ).getActualLongValue() );
}
// now force a "clock over"
entities[ increment ] = new Entity( "" + increment );
s.save( entities[ increment ] );
long expectedId = optimizer.getIncrementSize() + 1;
assertEquals( expectedId, entities[ optimizer.getIncrementSize() ].getId().longValue() );
- assertEquals( 2, optimizer.getLastSourceValue() ); // initialization + clokc-over
- assertEquals( increment + 1, optimizer.getLastValue() );
- assertEquals( ( increment * 2 ) + 1, optimizer.getHiValue() );
+ assertEquals( 2, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() ); // initialization + clock-over
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
+ assertEquals( ( increment * 2 ) + 1, ( (BasicHolder) optimizer.getHiValue() ).getActualLongValue() );
s.getTransaction().commit();
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/PooledForcedTableSequenceTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/PooledForcedTableSequenceTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/forcedtable/PooledForcedTableSequenceTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -2,14 +2,16 @@
import junit.framework.Test;
+import org.hibernate.Session;
+import org.hibernate.id.enhanced.OptimizerFactory;
+import org.hibernate.id.enhanced.SequenceStyleGenerator;
+import org.hibernate.id.enhanced.TableStructure;
import org.hibernate.junit.functional.DatabaseSpecificFunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.id.enhanced.OptimizerFactory;
-import org.hibernate.id.enhanced.SequenceStyleGenerator;
-import org.hibernate.id.enhanced.TableStructure;
-import org.hibernate.Session;
+import static org.hibernate.id.IdentifierGeneratorHelper.BasicHolder;
+
/**
* {@inheritDoc}
*
@@ -54,19 +56,21 @@
s.save( entities[i] );
long expectedId = i + 1;
assertEquals( expectedId, entities[i].getId().longValue() );
- assertEquals( 2, generator.getDatabaseStructure().getTimesAccessed() ); // initialization calls table twice
- assertEquals( increment + 1, optimizer.getLastSourceValue() ); // initialization calls table twice
- assertEquals( i + 1, optimizer.getLastValue() );
- assertEquals( increment + 1, optimizer.getLastSourceValue() );
+ // NOTE : initialization calls table twice
+ assertEquals( 2, generator.getDatabaseStructure().getTimesAccessed() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() );
+ assertEquals( i + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() );
}
// now force a "clock over"
entities[ increment ] = new Entity( "" + increment );
s.save( entities[ increment ] );
long expectedId = optimizer.getIncrementSize() + 1;
assertEquals( expectedId, entities[ optimizer.getIncrementSize() ].getId().longValue() );
- assertEquals( 3, generator.getDatabaseStructure().getTimesAccessed() ); // initialization (2) + clock over
- assertEquals( ( increment * 2 ) + 1, optimizer.getLastSourceValue() ); // initialization (2) + clock over
- assertEquals( increment + 1, optimizer.getLastValue() );
+ // initialization (2) + clock over
+ assertEquals( 3, generator.getDatabaseStructure().getTimesAccessed() );
+ assertEquals( ( increment * 2 ) + 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
s.getTransaction().commit();
s.beginTransaction();
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/BasicSequenceTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/BasicSequenceTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/BasicSequenceTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -8,6 +8,8 @@
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.persister.entity.EntityPersister;
+import static org.hibernate.id.IdentifierGeneratorHelper.BasicHolder;
+
/**
* {@inheritDoc}
*
@@ -41,7 +43,7 @@
long expectedId = i + 1;
assertEquals( expectedId, entities[i].getId().longValue() );
assertEquals( expectedId, generator.getDatabaseStructure().getTimesAccessed() );
- assertEquals( expectedId, generator.getOptimizer().getLastSourceValue() );
+ assertEquals( expectedId, ( (BasicHolder) generator.getOptimizer().getLastSourceValue() ).getActualLongValue() );
}
s.getTransaction().commit();
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/HiLoSequenceTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/HiLoSequenceTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/HiLoSequenceTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -9,6 +9,9 @@
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.persister.entity.EntityPersister;
+import static org.hibernate.id.IdentifierGeneratorHelper.BasicHolder;
+
+
/**
* {@inheritDoc}
*
@@ -42,17 +45,17 @@
entities[i] = new Entity( "" + ( i + 1 ) );
s.save( entities[i] );
assertEquals( 1, generator.getDatabaseStructure().getTimesAccessed() ); // initialization
- assertEquals( 1, optimizer.getLastSourceValue() ); // initialization
- assertEquals( i + 1, optimizer.getLastValue() );
- assertEquals( increment + 1, optimizer.getHiValue() );
+ assertEquals( 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() ); // initialization
+ assertEquals( i + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getHiValue() ).getActualLongValue() );
}
// now force a "clock over"
entities[ increment ] = new Entity( "" + increment );
s.save( entities[ increment ] );
assertEquals( 2, generator.getDatabaseStructure().getTimesAccessed() ); // initialization
- assertEquals( 2, optimizer.getLastSourceValue() ); // initialization
- assertEquals( increment + 1, optimizer.getLastValue() );
- assertEquals( ( increment * 2 ) + 1, optimizer.getHiValue() );
+ assertEquals( 2, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() ); // initialization
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
+ assertEquals( ( increment * 2 ) + 1, ( (BasicHolder) optimizer.getHiValue() ).getActualLongValue() );
s.getTransaction().commit();
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/PooledSequenceTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/PooledSequenceTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/sequence/PooledSequenceTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -9,6 +9,8 @@
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.Session;
+import static org.hibernate.id.IdentifierGeneratorHelper.BasicHolder;
+
/**
* {@inheritDoc}
*
@@ -42,16 +44,16 @@
entities[i] = new Entity( "" + ( i + 1 ) );
s.save( entities[i] );
assertEquals( 2, generator.getDatabaseStructure().getTimesAccessed() ); // initialization calls seq twice
- assertEquals( increment + 1, optimizer.getLastSourceValue() ); // initialization calls seq twice
- assertEquals( i + 1, optimizer.getLastValue() );
- assertEquals( increment + 1, optimizer.getLastSourceValue() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() ); // initialization calls seq twice
+ assertEquals( i + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() );
}
// now force a "clock over"
entities[ increment ] = new Entity( "" + increment );
s.save( entities[ increment ] );
assertEquals( 3, generator.getDatabaseStructure().getTimesAccessed() ); // initialization (2) + clock over
- assertEquals( ( increment * 2 ) + 1, optimizer.getLastSourceValue() ); // initialization (2) + clock over
- assertEquals( increment + 1, optimizer.getLastValue() );
+ assertEquals( ( increment * 2 ) + 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() ); // initialization (2) + clock over
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
s.getTransaction().commit();
s.beginTransaction();
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/BasicTableTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/BasicTableTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/BasicTableTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -8,6 +8,8 @@
import org.hibernate.id.enhanced.TableGenerator;
import org.hibernate.Session;
+import static org.hibernate.id.IdentifierGeneratorHelper.BasicHolder;
+
/**
* {@inheritDoc}
*
@@ -41,7 +43,7 @@
long expectedId = i + 1;
assertEquals( expectedId, entities[i].getId().longValue() );
assertEquals( expectedId, generator.getTableAccessCount() );
- assertEquals( expectedId, generator.getOptimizer().getLastSourceValue() );
+ assertEquals( expectedId, ( (BasicHolder) generator.getOptimizer().getLastSourceValue() ).getActualLongValue() );
}
s.getTransaction().commit();
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/HiLoTableTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/HiLoTableTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/HiLoTableTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -9,6 +9,8 @@
import org.hibernate.id.enhanced.TableGenerator;
import org.hibernate.Session;
+import static org.hibernate.id.IdentifierGeneratorHelper.BasicHolder;
+
/**
* {@inheritDoc}
*
@@ -42,17 +44,17 @@
entities[i] = new Entity( "" + ( i + 1 ) );
s.save( entities[i] );
assertEquals( 1, generator.getTableAccessCount() ); // initialization
- assertEquals( 1, optimizer.getLastSourceValue() ); // initialization
- assertEquals( i + 1, optimizer.getLastValue() );
- assertEquals( increment + 1, optimizer.getHiValue() );
+ assertEquals( 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() ); // initialization
+ assertEquals( i + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getHiValue() ).getActualLongValue() );
}
// now force a "clock over"
entities[ increment ] = new Entity( "" + increment );
s.save( entities[ increment ] );
assertEquals( 2, generator.getTableAccessCount() ); // initialization
- assertEquals( 2, optimizer.getLastSourceValue() ); // initialization
- assertEquals( increment + 1, optimizer.getLastValue() );
- assertEquals( ( increment * 2 ) + 1, optimizer.getHiValue() );
+ assertEquals( 2, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() ); // initialization
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
+ assertEquals( ( increment * 2 ) + 1, ( (BasicHolder) optimizer.getHiValue() ).getActualLongValue() );
s.getTransaction().commit();
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/PooledTableTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/PooledTableTest.java 2010-02-11 21:08:01 UTC (rev 18788)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/PooledTableTest.java 2010-02-12 06:22:52 UTC (rev 18789)
@@ -9,6 +9,8 @@
import org.hibernate.id.enhanced.TableGenerator;
import org.hibernate.Session;
+import static org.hibernate.id.IdentifierGeneratorHelper.BasicHolder;
+
/**
* {@inheritDoc}
*
@@ -42,16 +44,16 @@
entities[i] = new Entity( "" + ( i + 1 ) );
s.save( entities[i] );
assertEquals( 2, generator.getTableAccessCount() ); // initialization calls seq twice
- assertEquals( increment + 1, optimizer.getLastSourceValue() ); // initialization calls seq twice
- assertEquals( i + 1, optimizer.getLastValue() );
- assertEquals( increment + 1, optimizer.getLastSourceValue() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() ); // initialization calls seq twice
+ assertEquals( i + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() );
}
// now force a "clock over"
entities[ increment ] = new Entity( "" + increment );
s.save( entities[ increment ] );
assertEquals( 3, generator.getTableAccessCount() ); // initialization (2) + clock over
- assertEquals( ( increment * 2 ) + 1, optimizer.getLastSourceValue() ); // initialization (2) + clock over
- assertEquals( increment + 1, optimizer.getLastValue() );
+ assertEquals( ( increment * 2 ) + 1, ( (BasicHolder) optimizer.getLastSourceValue() ).getActualLongValue() ); // initialization (2) + clock over
+ assertEquals( increment + 1, ( (BasicHolder) optimizer.getLastValue() ).getActualLongValue() );
s.getTransaction().commit();
s.beginTransaction();
More information about the hibernate-commits
mailing list