Hibernate SVN: r19480 - in core/branches/Branch_3_5: core/src/main/java/org/hibernate/cfg and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2010-05-12 14:19:00 -0400 (Wed, 12 May 2010)
New Revision: 19480
Modified:
core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/Environment.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/HbmBinder.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/mapping/SimpleValue.java
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java
Log:
HHH-5218 - Provide a new "pooled value" based optimizer which interprets the database value as the low boundary instead of upper boundary
Modified: core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java
===================================================================
--- core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2010-05-12 17:17:45 UTC (rev 19479)
+++ core/branches/Branch_3_5/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2010-05-12 18:19:00 UTC (rev 19480)
@@ -434,9 +434,7 @@
* Find the column owner (ie PersistentClass or Join) of columnName.
* If columnName is null or empty, persistentClass is returned
*/
- public static Object findColumnOwner(
- PersistentClass persistentClass, String columnName, ExtendedMappings mappings
- ) {
+ public static Object findColumnOwner(PersistentClass persistentClass, String columnName, ExtendedMappings mappings) {
if ( StringHelper.isEmpty( columnName ) ) {
return persistentClass; //shortcut for implicit referenced column names
}
@@ -475,9 +473,11 @@
* apply an id generator to a SimpleValue
*/
public static void makeIdGenerator(
- SimpleValue id, String generatorType, String generatorName, ExtendedMappings mappings,
- Map<String, IdGenerator> localGenerators
- ) {
+ SimpleValue id,
+ String generatorType,
+ String generatorName,
+ ExtendedMappings mappings,
+ Map<String, IdGenerator> localGenerators) {
Table table = id.getTable();
table.setIdentifierValue( id );
//generator settings
@@ -520,7 +520,16 @@
params.setProperty( (String) elt.getKey(), (String) elt.getValue() );
}
}
- if ( "assigned".equals( generatorType ) ) id.setNullValue( "undefined" );
+
+ if ( "assigned".equals( generatorType ) ) {
+ id.setNullValue( "undefined" );
+ }
+
+ final String pooledOptPreference = mappings.getConfigurationProperties().getProperty( Environment.PREFER_POOLED_VALUES_LO );
+ if ( pooledOptPreference != null ) {
+ params.setProperty( Environment.PREFER_POOLED_VALUES_LO, pooledOptPreference );
+ }
+
id.setIdentifierGeneratorProperties( params );
}
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/Environment.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/Environment.java 2010-05-12 17:17:45 UTC (rev 19479)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/Environment.java 2010-05-12 18:19:00 UTC (rev 19480)
@@ -519,6 +519,12 @@
public static final String JPAQL_STRICT_COMPLIANCE= "hibernate.query.jpaql_strict_compliance";
+ /**
+ * When using pooled {@link org.hibernate.id.enhanced.Optimizer optimizers}, prefer interpreting the
+ * database value as the lower (lo) boundary. The default is to interpret it as the high boundary.
+ */
+ public static final String PREFER_POOLED_VALUES_LO = "hibernate.id.optimizer.pooled.prefer_lo";
+
private static final BytecodeProvider BYTECODE_PROVIDER_INSTANCE;
private static final boolean ENABLE_BINARY_STREAMS;
private static final boolean ENABLE_REFLECTION_OPTIMIZER;
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/HbmBinder.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/HbmBinder.java 2010-05-12 17:17:45 UTC (rev 19479)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/cfg/HbmBinder.java 2010-05-12 18:19:00 UTC (rev 19480)
@@ -2091,6 +2091,11 @@
params.setProperty( childNode.attributeValue( "name" ), childNode.getTextTrim() );
}
+ final String pooledOptPreference = mappings.getConfigurationProperties().getProperty( Environment.PREFER_POOLED_VALUES_LO );
+ if ( pooledOptPreference != null ) {
+ params.setProperty( Environment.PREFER_POOLED_VALUES_LO, pooledOptPreference );
+ }
+
model.setIdentifierGeneratorProperties( params );
}
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2010-05-12 17:17:45 UTC (rev 19479)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2010-05-12 18:19:00 UTC (rev 19480)
@@ -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.enhanced;
@@ -46,6 +45,7 @@
public static final String HILO = "hilo";
public static final String LEGACY_HILO = "legacy-hilo";
public static final String POOL = "pooled";
+ public static final String POOL_LO = "pooled-lo";
private static Class[] CTOR_SIG = new Class[] { Class.class, int.class };
@@ -92,6 +92,9 @@
else if ( POOL.equals( type ) ) {
optimizerClassName = PooledOptimizer.class.getName();
}
+ else if ( POOL_LO.equals( type ) ) {
+ optimizerClassName = PooledLoOptimizer.class.getName();
+ }
else {
optimizerClassName = type;
}
@@ -386,6 +389,9 @@
* 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.
+ * <p/>
+ * Note if you prefer that the database value be interpreted as the bottom end of our current range,
+ * then use the {@link PooledLoOptimizer} strategy
*/
public static class PooledOptimizer extends OptimizerSupport implements InitialValueAwareOptimizer {
private IntegralDataTypeHolder hiValue;
@@ -463,4 +469,39 @@
this.initialValue = initialValue;
}
}
+
+ public static class PooledLoOptimizer extends OptimizerSupport {
+ private IntegralDataTypeHolder lastSourceValue; // last value read from db source
+ private IntegralDataTypeHolder value; // the current generator value
+
+ public PooledLoOptimizer(Class returnClass, int incrementSize) {
+ super( returnClass, incrementSize );
+ if ( incrementSize < 1 ) {
+ throw new HibernateException( "increment size cannot be less than 1" );
+ }
+ if ( log.isTraceEnabled() ) {
+ log.trace( "creating pooled optimizer (lo) with [incrementSize=" + incrementSize + "; returnClass=" + returnClass.getName() + "]" );
+ }
+ }
+
+ public Serializable generate(AccessCallback callback) {
+ if ( lastSourceValue == null || ! value.lt( lastSourceValue.copy().add( incrementSize ) ) ) {
+ lastSourceValue = callback.getNextValue();
+ value = lastSourceValue.copy();
+ // handle cases where initial-value is less that one (hsqldb for instance).
+ while ( value.lt( 1 ) ) {
+ value.increment();
+ }
+ }
+ return value.makeValueThenIncrement();
+ }
+
+ public IntegralDataTypeHolder getLastSourceValue() {
+ return lastSourceValue;
+ }
+
+ public boolean applyIncrementSizeToSourceValues() {
+ return true;
+ }
+ }
}
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java 2010-05-12 17:17:45 UTC (rev 19479)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java 2010-05-12 18:19:00 UTC (rev 19480)
@@ -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.enhanced;
@@ -30,6 +29,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.hibernate.cfg.Environment;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.Configurable;
import org.hibernate.HibernateException;
@@ -280,8 +280,13 @@
* @return The optimizer strategy (name)
*/
protected String determineOptimizationStrategy(Properties params, int incrementSize) {
- String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
- return PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
+ // if the increment size is greater than one, we prefer pooled optimization; but we
+ // need to see if the user prefers POOL or POOL_LO...
+ String defaultPooledOptimizerStrategy = PropertiesHelper.getBoolean( Environment.PREFER_POOLED_VALUES_LO, params, false )
+ ? OptimizerFactory.POOL_LO
+ : OptimizerFactory.POOL;
+ String defaultOptimizerStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : defaultPooledOptimizerStrategy;
+ return PropertiesHelper.getString( OPT_PARAM, params, defaultOptimizerStrategy );
}
/**
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java 2010-05-12 17:17:45 UTC (rev 19479)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java 2010-05-12 18:19:00 UTC (rev 19480)
@@ -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.enhanced;
@@ -37,6 +36,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.hibernate.cfg.Environment;
import org.hibernate.engine.TransactionHelper;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.id.IdentifierGeneratorHelper;
@@ -65,14 +65,14 @@
* performing generation, which would mean that we would have a row in the generator
* table for each entity name. Or any configuration really; the setup is very flexible.
* <p/>
- * In this respect it is very simliar to the legacy
+ * In this respect it is very similar to the legacy
* {@link org.hibernate.id.MultipleHiLoPerTableGenerator} in terms of the
* underlying storage structure (namely a single table capable of holding
* multiple generator values). The differentiator is, as with
* {@link SequenceStyleGenerator} as well, the externalized notion
* of an optimizer.
* <p/>
- * <b>NOTE</b> that by default we use a single row for all genertators (based
+ * <b>NOTE</b> that by default we use a single row for all generators (based
* on {@link #DEF_SEGMENT_VALUE}). The configuration parameter
* {@link #CONFIG_PREFER_SEGMENT_PER_ENTITY} can be used to change that to
* instead default to using a row for each entity name.
@@ -303,8 +303,14 @@
this.updateQuery = buildUpdateQuery();
this.insertQuery = buildInsertQuery();
- String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
- String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
+
+ // if the increment size is greater than one, we prefer pooled optimization; but we
+ // need to see if the user prefers POOL or POOL_LO...
+ String defaultPooledOptimizerStrategy = PropertiesHelper.getBoolean( Environment.PREFER_POOLED_VALUES_LO, params, false )
+ ? OptimizerFactory.POOL_LO
+ : OptimizerFactory.POOL;
+ final String defaultOptimizerStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : defaultPooledOptimizerStrategy;
+ final String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defaultOptimizerStrategy );
optimizer = OptimizerFactory.buildOptimizer(
optimizationStrategy,
identifierType.getReturnedClass(),
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/mapping/SimpleValue.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/mapping/SimpleValue.java 2010-05-12 17:17:45 UTC (rev 19479)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/mapping/SimpleValue.java 2010-05-12 18:19:00 UTC (rev 19480)
@@ -31,6 +31,7 @@
import org.hibernate.FetchMode;
import org.hibernate.MappingException;
+import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.Mapping;
import org.hibernate.id.IdentifierGenerator;
Modified: core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java
===================================================================
--- core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java 2010-05-12 17:17:45 UTC (rev 19479)
+++ core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java 2010-05-12 18:19:00 UTC (rev 19480)
@@ -1,3 +1,26 @@
+/*
+ * 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.enhanced;
import junit.framework.Assert;
@@ -100,35 +123,136 @@
public void testSubsequentPooledOptimizerUsage() {
// test the pooled optimizer in situation where the sequence is already beyond its initial value on init.
// cheat by telling the sequence to start with 1000
- final SourceMock sequence = new SourceMock( 1000, 3, 5 );
+ final SourceMock sequence = new SourceMock( 1001, 3, 5 );
// but tell the optimizer the start-with is 1
final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 3, 1 );
assertEquals( 5, sequence.getTimesCalled() );
- assertEquals( 1000, sequence.getCurrentValue() );
+ assertEquals( 1001, sequence.getCurrentValue() );
Long next = (Long) optimizer.generate( sequence );
- assertEquals( 1000, next.intValue() );
+ assertEquals( 1001, next.intValue() );
assertEquals( (5+1), sequence.getTimesCalled() );
- assertEquals( (1000+3), sequence.getCurrentValue() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
next = (Long) optimizer.generate( sequence );
- assertEquals( 1001, next.intValue() );
+ assertEquals( (1001+1), next.intValue() );
assertEquals( (5+1), sequence.getTimesCalled() );
- assertEquals( (1000+3), sequence.getCurrentValue() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
next = (Long) optimizer.generate( sequence );
- assertEquals( 1002, next.intValue() );
+ assertEquals( (1001+2), next.intValue() );
assertEquals( (5+1), sequence.getTimesCalled() );
- assertEquals( (1000+3), sequence.getCurrentValue() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
// force a "clock over"
next = (Long) optimizer.generate( sequence );
- assertEquals( 1003, next.intValue() );
+ assertEquals( (1001+3), next.intValue() );
assertEquals( (5+2), sequence.getTimesCalled() );
- assertEquals( (1000+6), sequence.getCurrentValue() );
+ assertEquals( (1001+6), sequence.getCurrentValue() );
}
+ public void testBasicPooledLoOptimizerUsage() {
+ final SourceMock sequence = new SourceMock( 1, 3 );
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL_LO, Long.class, 3 );
+
+ assertEquals( 0, sequence.getTimesCalled() );
+ assertEquals( -1, sequence.getCurrentValue() );
+
+ Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 1, next.intValue() );
+ assertEquals( 1, sequence.getTimesCalled() );
+ assertEquals( 1, sequence.getCurrentValue() );
+
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 2, next.intValue() );
+ assertEquals( 1, sequence.getTimesCalled() );
+ assertEquals( 1, sequence.getCurrentValue() );
+
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 3, next.intValue() );
+ assertEquals( 1, sequence.getTimesCalled() );
+ assertEquals( 1, sequence.getCurrentValue() );
+
+// // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 4, next.intValue() );
+ assertEquals( 2, sequence.getTimesCalled() );
+ assertEquals( (1+3), sequence.getCurrentValue() );
+ }
+
+ public void testSubsequentPooledLoOptimizerUsage() {
+ // test the pooled optimizer in situation where the sequence is already beyond its initial value on init.
+ // cheat by telling the sequence to start with 1000
+ final SourceMock sequence = new SourceMock( 1001, 3, 5 );
+ // but tell the optimizer the start-with is 1
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 3, 1 );
+
+ assertEquals( 5, sequence.getTimesCalled() );
+ assertEquals( 1001, sequence.getCurrentValue() );
+
+ Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( (1001), next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
+
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( (1001+1), next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
+
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( (1001+2), next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1001+3), sequence.getCurrentValue() );
+
+// // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( (1001+3), next.intValue() );
+ assertEquals( (5+2), sequence.getTimesCalled() );
+ assertEquals( (1001+6), sequence.getCurrentValue() );
+ }
+
+ public void testRecoveredPooledOptimizerUsage() {
+ final SourceMock sequence = new SourceMock( 1, 3 );
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 3, 1 );
+
+ assertEquals( 0, sequence.getTimesCalled() );
+ assertEquals( -1, sequence.getCurrentValue() );
+
+ Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 1, next.intValue() );
+ assertEquals( 2, sequence.getTimesCalled() );
+ assertEquals( 4, sequence.getCurrentValue() );
+
+ // app ends, and starts back up (we should "lose" only 2 and 3 as id values)
+ final Optimizer optimizer2 = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 3, 1 );
+ next = ( Long ) optimizer2.generate( sequence );
+ assertEquals( 4, next.intValue() );
+ assertEquals( 3, sequence.getTimesCalled() );
+ assertEquals( 7, sequence.getCurrentValue() );
+ }
+
+ public void testRecoveredPooledLoOptimizerUsage() {
+ final SourceMock sequence = new SourceMock( 1, 3 );
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL_LO, Long.class, 3, 1 );
+
+ assertEquals( 0, sequence.getTimesCalled() );
+ assertEquals( -1, sequence.getCurrentValue() );
+
+ Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 1, next.intValue() );
+ assertEquals( 1, sequence.getTimesCalled() );
+ assertEquals( 1, sequence.getCurrentValue() );
+
+ // app ends, and starts back up (we should "lose" only 2 and 3 as id values)
+ final Optimizer optimizer2 = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL_LO, Long.class, 3, 1 );
+ next = ( Long ) optimizer2.generate( sequence );
+ assertEquals( 4, next.intValue() );
+ assertEquals( 2, sequence.getTimesCalled() );
+ assertEquals( 4, sequence.getCurrentValue() );
+ }
+
private static class SourceMock implements AccessCallback {
private IdentifierGeneratorHelper.BasicHolder value = new IdentifierGeneratorHelper.BasicHolder( Long.class );
private long initialValue;
@@ -151,6 +275,7 @@
this.initialValue = 1;
}
else {
+ this.value.initialize( -1 );
this.initialValue = initialValue;
}
}
@@ -182,5 +307,4 @@
return value == null ? -1 : value.getActualLongValue();
}
}
-
}
Modified: core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java
===================================================================
--- core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12 17:17:45 UTC (rev 19479)
+++ core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12 18:19:00 UTC (rev 19480)
@@ -1,3 +1,26 @@
+/*
+ * 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.enhanced;
import java.util.Properties;
@@ -9,6 +32,7 @@
import org.hibernate.Hibernate;
import org.hibernate.MappingException;
+import org.hibernate.cfg.Environment;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.cfg.ObjectNameNormalizer;
import org.hibernate.dialect.Dialect;
@@ -179,7 +203,23 @@
assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
Assert.assertEquals( 20, generator.getOptimizer().getIncrementSize() );
Assert.assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
+ }
+ public void testPreferPooledLoSettingHonored() {
+ final Dialect dialect = new PooledSequenceDialect();
+
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
+
+ props.setProperty( Environment.PREFER_POOLED_VALUES_LO, "true" );
+ generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledLoOptimizer.class, generator.getOptimizer().getClass() );
}
private static class TableDialect extends Dialect {
14 years, 8 months
Hibernate SVN: r19479 - in jpamodelgen/trunk: src/main/java/org/hibernate/jpamodelgen/annotation and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2010-05-12 13:17:45 -0400 (Wed, 12 May 2010)
New Revision: 19479
Added:
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/AbstractEntity.java
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/Person.java
Modified:
jpamodelgen/trunk/pom.xml
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java
jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/TypeUtils.java
jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/InheritanceTest.java
Log:
METAGEN-29 adding handling of type variables in AnnotationMetaEntity
Modified: jpamodelgen/trunk/pom.xml
===================================================================
--- jpamodelgen/trunk/pom.xml 2010-05-12 15:13:47 UTC (rev 19478)
+++ jpamodelgen/trunk/pom.xml 2010-05-12 17:17:45 UTC (rev 19479)
@@ -1,4 +1,6 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
@@ -90,6 +92,27 @@
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>1.0-beta-1</version>
+ <executions>
+ <execution>
+ <id>enforce-java</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <rules>
+ <requireJavaVersion>
+ <!-- require JDK 1.6 to run the build -->
+ <version>[1.6,)</version>
+ </requireJavaVersion>
+ </rules>
+ </configuration>
+ </plugin>
+ <plugin>
<groupId>org.jboss.maven.plugins</groupId>
<artifactId>maven-injection-plugin</artifactId>
<version>1.0.2</version>
@@ -202,7 +225,7 @@
<configuration>
<archive>
<manifestEntries>
- <Created-By>${java.version} (${java.vendor})</Created-By>
+ <Created-By>${java.version} (${java.vendor})</Created-By>
<Implementation-Title>${pom.name}</Implementation-Title>
<Implementation-URL>http://www.jboss.org/</Implementation-URL>
<Implementation-Version>${pom.version}</Implementation-Version>
@@ -243,7 +266,9 @@
<autoVersionSubmodules>true</autoVersionSubmodules>
<allowTimestampedSnapshots>true</allowTimestampedSnapshots>
<remoteTagging>true</remoteTagging>
- <goals>package deploy javadoc:javadoc org.jboss.maven.plugins:maven-jdocbook-plugin:2.2.1:resources org.jboss.maven.plugins:maven-jdocbook-plugin:2.2.1:generate assembly:assembly</goals>
+ <goals>package deploy javadoc:javadoc org.jboss.maven.plugins:maven-jdocbook-plugin:2.2.1:resources
+ org.jboss.maven.plugins:maven-jdocbook-plugin:2.2.1:generate assembly:assembly
+ </goals>
</configuration>
</plugin>
<plugin>
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java 2010-05-12 15:13:47 UTC (rev 19478)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/annotation/AnnotationMetaEntity.java 2010-05-12 17:17:45 UTC (rev 19479)
@@ -35,6 +35,7 @@
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.persistence.AccessType;
@@ -215,6 +216,15 @@
return new AnnotationMetaSingleAttribute( parent, element, TypeUtils.toTypeString( t ) );
}
+ public AnnotationMetaAttribute visitTypeVariable(TypeVariable t, Element element) {
+ // METAGEN-29 - for a type variable we use the upper bound
+ TypeMirror mirror = t.getUpperBound();
+ TypeMirror erasedType = context.getTypeUtils().erasure( mirror );
+ return new AnnotationMetaSingleAttribute(
+ parent, element, erasedType.toString()
+ );
+ }
+
@Override
public AnnotationMetaAttribute visitDeclared(DeclaredType declaredType, Element element) {
TypeElement returnedElement = ( TypeElement ) context.getTypeUtils().asElement( declaredType );
Modified: jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/TypeUtils.java
===================================================================
--- jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/TypeUtils.java 2010-05-12 15:13:47 UTC (rev 19478)
+++ jpamodelgen/trunk/src/main/java/org/hibernate/jpamodelgen/util/TypeUtils.java 2010-05-12 17:17:45 UTC (rev 19479)
@@ -206,7 +206,7 @@
if ( accessTypeInfo != null && accessTypeInfo.isAccessTypeResolved() ) {
context.logMessage(
Diagnostic.Kind.OTHER,
- "AccessType for " + searchedElement.toString() + "found in cache: " + accessTypeInfo
+ "AccessType for " + searchedElement.toString() + " found in cache: " + accessTypeInfo
);
return;
}
Added: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/AbstractEntity.java
===================================================================
--- jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/AbstractEntity.java (rev 0)
+++ jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/AbstractEntity.java 2010-05-12 17:17:45 UTC (rev 19479)
@@ -0,0 +1,35 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.jpamodelgen.test.inheritance;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+
+@MappedSuperclass
+public abstract class AbstractEntity<T> {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ private T foo;
+
+ public AbstractEntity() {
+ }
+}
\ No newline at end of file
Property changes on: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/AbstractEntity.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/InheritanceTest.java
===================================================================
--- jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/InheritanceTest.java 2010-05-12 15:13:47 UTC (rev 19478)
+++ jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/InheritanceTest.java 2010-05-12 17:17:45 UTC (rev 19479)
@@ -21,6 +21,8 @@
import org.hibernate.jpamodelgen.test.util.CompilationTest;
+import static org.hibernate.jpamodelgen.test.util.TestUtil.assertAttributeTypeInMetaModelFor;
+import static org.hibernate.jpamodelgen.test.util.TestUtil.assertPresenceOfFieldInMetamodelFor;
import static org.hibernate.jpamodelgen.test.util.TestUtil.assertSuperClassRelationShipInMetamodel;
/**
@@ -29,14 +31,22 @@
*/
public class InheritanceTest extends CompilationTest {
@Test
- public void testSuperEntity() throws Exception {
+ public void testInheritance() throws Exception {
+
+ // entity inheritance
assertSuperClassRelationShipInMetamodel( Customer.class, User.class );
- }
- @Test
- public void testMappedSuperclass() throws Exception {
+
+ // mapped super class
assertSuperClassRelationShipInMetamodel( House.class, Building.class );
assertSuperClassRelationShipInMetamodel( Building.class, Area.class );
+
+ // METAGEN-29
+ assertSuperClassRelationShipInMetamodel( Person.class, AbstractEntity.class );
+ assertPresenceOfFieldInMetamodelFor( AbstractEntity.class, "foo", "Property should exist - METAGEN-29" );
+ assertAttributeTypeInMetaModelFor(
+ AbstractEntity.class, "foo", Object.class, "Object is the upper bound of foo "
+ );
}
@Override
Added: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/Person.java
===================================================================
--- jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/Person.java (rev 0)
+++ jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/Person.java 2010-05-12 17:17:45 UTC (rev 19479)
@@ -0,0 +1,40 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.jpamodelgen.test.inheritance;
+
+import javax.persistence.Entity;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class Person extends AbstractEntity<String> {
+ private String name;
+
+ protected Person() {
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file
Property changes on: jpamodelgen/trunk/src/test/java/org/hibernate/jpamodelgen/test/inheritance/Person.java
___________________________________________________________________
Name: svn:keywords
+ Id
14 years, 8 months
Hibernate SVN: r19478 - in core/trunk: core/src/test/java/org/hibernate/id and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2010-05-12 11:13:47 -0400 (Wed, 12 May 2010)
New Revision: 19478
Added:
core/trunk/core/src/test/java/org/hibernate/id/enhanced/
core/trunk/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java
core/trunk/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java
Removed:
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java
Modified:
core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.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
Log:
HHH-5217 - Minimize double sequence value reads in PooledOptimizer
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-05-12 15:13:03 UTC (rev 19477)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2010-05-12 15:13:47 UTC (rev 19478)
@@ -44,10 +44,40 @@
public static final String NONE = "none";
public static final String HILO = "hilo";
+ public static final String LEGACY_HILO = "legacy-hilo";
public static final String POOL = "pooled";
private static Class[] CTOR_SIG = new Class[] { Class.class, int.class };
+ /**
+ * Marker interface for optimizer which wish to know the user-specified initial value.
+ * <p/>
+ * Used instead of constructor injection since that is already a public understanding and
+ * because not all optimizers care.
+ */
+ public static interface InitialValueAwareOptimizer {
+ /**
+ * Reports the user specified initial value to the optimizer.
+ * <p/>
+ * <tt>-1</tt> is used to indicate that the user did not specify.
+ *
+ * @param initialValue The initial value specified by the user, or <tt>-1</tt> to indicate that the
+ * user did not specify.
+ */
+ public void injectInitialValue(long initialValue);
+ }
+
+ /**
+ * Builds an optimizer
+ *
+ * @param type The optimizer type, either a short-hand name or the {@link Optimizer} class name.
+ * @param returnClass The generated value java type
+ * @param incrementSize The increment size.
+ *
+ * @return The built optimizer
+ *
+ * @deprecated Use {@link #buildOptimizer(String, Class, int, long)} instead
+ */
@SuppressWarnings({ "UnnecessaryBoxing" })
public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize) {
String optimizerClassName;
@@ -57,6 +87,9 @@
else if ( HILO.equals( type ) ) {
optimizerClassName = HiLoOptimizer.class.getName();
}
+ else if ( LEGACY_HILO.equals( type ) ) {
+ optimizerClassName = LegacyHiLoAlgorithmOptimizer.class.getName();
+ }
else if ( POOL.equals( type ) ) {
optimizerClassName = PooledOptimizer.class.getName();
}
@@ -70,14 +103,34 @@
return ( Optimizer ) ctor.newInstance( returnClass, Integer.valueOf( incrementSize ) );
}
catch( Throwable ignore ) {
- // intentionally empty
+ log.warn( "Unable to instantiate specified optimizer [{}], falling back to noop", type );
}
// the default...
return new NoopOptimizer( returnClass, incrementSize );
}
+
/**
+ * Builds an optimizer
+ *
+ * @param type The optimizer type, either a short-hand name or the {@link Optimizer} class name.
+ * @param returnClass The generated value java type
+ * @param incrementSize The increment size.
+ * @param explicitInitialValue The user supplied initial-value (-1 indicates the user did not specify).
+ *
+ * @return The built optimizer
+ */
+ @SuppressWarnings({ "UnnecessaryBoxing", "deprecation" })
+ public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize, long explicitInitialValue) {
+ final Optimizer optimizer = buildOptimizer( type, returnClass, incrementSize );
+ if ( InitialValueAwareOptimizer.class.isInstance( optimizer ) ) {
+ ( (InitialValueAwareOptimizer) optimizer ).injectInitialValue( explicitInitialValue );
+ }
+ return optimizer;
+ }
+
+ /**
* Common support for optimizer implementations.
*/
public static abstract class OptimizerSupport implements Optimizer {
@@ -335,9 +388,10 @@
* {@link HiLoOptimizer} except that here the bucket ranges are actually
* encoded into the database structures.
*/
- public static class PooledOptimizer extends OptimizerSupport {
+ public static class PooledOptimizer extends OptimizerSupport implements InitialValueAwareOptimizer {
private IntegralDataTypeHolder hiValue;
private IntegralDataTypeHolder value;
+ private long initialValue = -1;
public PooledOptimizer(Class returnClass, int incrementSize) {
super( returnClass, incrementSize );
@@ -362,7 +416,14 @@
// we are using a sequence...
log.info( "pooled optimizer source reported [" + value + "] as the initial value; use of 1 or greater highly recommended" );
}
- hiValue = callback.getNextValue();
+ if ( ( initialValue == -1 && value.lt( incrementSize ) ) || value.eq( initialValue ) ) {
+ // the call to obtain next-value just gave us the initialValue
+ hiValue = callback.getNextValue();
+ }
+ else {
+ hiValue = value;
+ value = hiValue.copy().subtract( incrementSize );
+ }
}
else if ( ! hiValue.gt( value ) ) {
hiValue = callback.getNextValue();
@@ -395,5 +456,12 @@
public IntegralDataTypeHolder getLastValue() {
return value.copy().decrement();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void injectInitialValue(long initialValue) {
+ this.initialValue = initialValue;
+ }
}
}
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-05-12 15:13:03 UTC (rev 19477)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java 2010-05-12 15:13:47 UTC (rev 19478)
@@ -187,8 +187,12 @@
initialValue,
incrementSize
);
-
- this.optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
+ this.optimizer = OptimizerFactory.buildOptimizer(
+ optimizationStrategy,
+ identifierType.getReturnedClass(),
+ incrementSize,
+ PropertiesHelper.getInt( INITIAL_PARAM, params, -1 )
+ );
this.databaseStructure.prepare( optimizer );
}
@@ -305,7 +309,9 @@
* @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 An abstraction for the actual database structure in use (table vs. sequence).
*/
protected DatabaseStructure buildDatabaseStructure(
Type type,
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-05-12 15:13:03 UTC (rev 19477)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java 2010-05-12 15:13:47 UTC (rev 19478)
@@ -303,9 +303,14 @@
this.updateQuery = buildUpdateQuery();
this.insertQuery = buildInsertQuery();
- String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
- String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
- optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
+ final String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
+ final String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
+ optimizer = OptimizerFactory.buildOptimizer(
+ optimizationStrategy,
+ identifierType.getReturnedClass(),
+ incrementSize,
+ PropertiesHelper.getInt( INITIAL_PARAM, params, -1 )
+ );
}
/**
@@ -430,8 +435,8 @@
String query = "select " + StringHelper.qualify( alias, valueColumnName ) +
" from " + tableName + ' ' + alias +
" where " + StringHelper.qualify( alias, segmentColumnName ) + "=?";
- LockOptions lockOptions = new LockOptions(LockMode.UPGRADE);
- lockOptions.setAliasSpecificLockMode( alias, LockMode.UPGRADE );
+ LockOptions lockOptions = new LockOptions( LockMode.PESSIMISTIC_WRITE );
+ lockOptions.setAliasSpecificLockMode( alias, LockMode.PESSIMISTIC_WRITE );
Map updateTargetColumnsMap = Collections.singletonMap( alias, new String[] { valueColumnName } );
return dialect.applyLocksToSql( query, lockOptions, updateTargetColumnsMap );
}
Copied: core/trunk/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java (from rev 19411, core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java)
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java 2010-05-12 15:13:47 UTC (rev 19478)
@@ -0,0 +1,235 @@
+/*
+ * 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.enhanced;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.hibernate.id.IdentifierGeneratorHelper;
+import org.hibernate.id.IntegralDataTypeHolder;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+@SuppressWarnings({ "deprecation" })
+public class OptimizerUnitTest extends TestCase {
+ public OptimizerUnitTest(String string) {
+ super( string );
+ }
+
+ public static Test suite() {
+ return new TestSuite( OptimizerUnitTest.class );
+ }
+
+ public void testBasicNoOptimizerUsage() {
+ // test historic sequence behavior, where the initial values start at 1...
+ SourceMock sequence = new SourceMock( 1 );
+ Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
+ for ( int i = 1; i < 11; i++ ) {
+ final Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( i, next.intValue() );
+ }
+ assertEquals( 10, sequence.getTimesCalled() );
+ assertEquals( 10, sequence.getCurrentValue() );
+
+ // test historic table behavior, where the initial values started at 0 (we now force 1 to be the first used id value)
+ sequence = new SourceMock( 0 );
+ optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
+ for ( int i = 1; i < 11; i++ ) {
+ final Long next = ( Long ) optimizer.generate( sequence );
+ assertEquals( i, next.intValue() );
+ }
+ assertEquals( 11, sequence.getTimesCalled() ); // an extra time to get to 1 initially
+ assertEquals( 10, sequence.getCurrentValue() );
+ }
+
+ public void testBasicHiLoOptimizerUsage() {
+ int increment = 10;
+ Long next;
+
+ // test historic sequence behavior, where the initial values start at 1...
+ SourceMock sequence = new SourceMock( 1 );
+ Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
+ for ( int i = 1; i <= increment; i++ ) {
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( i, next.intValue() );
+ }
+ assertEquals( 1, sequence.getTimesCalled() ); // once to initialze state
+ assertEquals( 1, sequence.getCurrentValue() );
+ // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 11, next.intValue() );
+ assertEquals( 2, sequence.getTimesCalled() );
+ assertEquals( 2, sequence.getCurrentValue() );
+
+ // test historic table behavior, where the initial values started at 0 (we now force 1 to be the first used id value)
+ sequence = new SourceMock( 0 );
+ optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
+ for ( int i = 1; i <= increment; i++ ) {
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( i, next.intValue() );
+ }
+ assertEquals( 2, sequence.getTimesCalled() ); // here have have an extra call to get to 1 initially
+ assertEquals( 1, sequence.getCurrentValue() );
+ // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 11, next.intValue() );
+ assertEquals( 3, sequence.getTimesCalled() );
+ assertEquals( 2, sequence.getCurrentValue() );
+ }
+
+ public void testBasicPooledOptimizerUsage() {
+ Long next;
+ // test historic sequence behavior, where the initial values start at 1...
+ SourceMock sequence = new SourceMock( 1, 10 );
+ Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 10 );
+ for ( int i = 1; i < 11; i++ ) {
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( i, next.intValue() );
+ }
+ assertEquals( 2, sequence.getTimesCalled() ); // twice to initialize state
+ assertEquals( 11, sequence.getCurrentValue() );
+ // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ assertEquals( 11, next.intValue() );
+ assertEquals( 3, sequence.getTimesCalled() );
+ assertEquals( 21, sequence.getCurrentValue() );
+ }
+
+ public void testSubsequentPooledOptimizerUsage() {
+ // test the pooled optimizer in situation where the sequence is already beyond its initial value on init.
+ // cheat by telling the sequence to start with 1000
+ final SourceMock sequence = new SourceMock( 1000, 3, 5 );
+ // but tell the optimizer the start-with is 1
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 3, 1 );
+
+ assertEquals( 5, sequence.getTimesCalled() );
+ assertEquals( 1000, sequence.getCurrentValue() );
+
+ Long next = (Long) optimizer.generate( sequence );
+ assertEquals( 1000, next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1000+3), sequence.getCurrentValue() );
+
+ next = (Long) optimizer.generate( sequence );
+ assertEquals( 1001, next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1000+3), sequence.getCurrentValue() );
+
+ next = (Long) optimizer.generate( sequence );
+ assertEquals( 1002, next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1000+3), sequence.getCurrentValue() );
+
+ // force a "clock over"
+ next = (Long) optimizer.generate( sequence );
+ assertEquals( 1003, next.intValue() );
+ assertEquals( (5+2), sequence.getTimesCalled() );
+ assertEquals( (1000+6), sequence.getCurrentValue() );
+ }
+
+ private static class SourceMock implements AccessCallback {
+ private IdentifierGeneratorHelper.BasicHolder value = new IdentifierGeneratorHelper.BasicHolder( Long.class );
+ private long initialValue;
+ private int increment;
+ private int timesCalled = 0;
+
+ public SourceMock(long initialValue) {
+ this( initialValue, 1 );
+ }
+
+ public SourceMock(long initialValue, int increment) {
+ this( initialValue, increment, 0 );
+ }
+
+ public SourceMock(long initialValue, int increment, int timesCalled) {
+ this.increment = increment;
+ this.timesCalled = timesCalled;
+ if ( timesCalled != 0 ) {
+ this.value.initialize( initialValue );
+ this.initialValue = 1;
+ }
+ else {
+ this.initialValue = initialValue;
+ }
+ }
+
+ public IntegralDataTypeHolder getNextValue() {
+ try {
+ if ( timesCalled == 0 ) {
+ initValue();
+ return value.copy();
+ }
+ else {
+ return value.add( increment ).copy();
+ }
+ }
+ finally {
+ timesCalled++;
+ }
+ }
+
+ private void initValue() {
+ this.value.initialize( initialValue );
+ }
+
+ public int getTimesCalled() {
+ return timesCalled;
+ }
+
+ public long getCurrentValue() {
+ return value == null ? -1 : value.getActualLongValue();
+ }
+ }
+
+// public void testNoopDumping() {
+// SourceMock sequence = new SourceMock( 1 );
+// Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
+// for ( int i = 1; i <= 41; i++ ) {
+// System.out.println( i + " => " + optimizer.generate( sequence ) + " (" + sequence.getCurrentValue() + ")" );
+// }
+// }
+//
+// public void testHiLoDumping() {
+// int increment = 10;
+// SourceMock sequence = new SourceMock( 1 );
+// Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
+// for ( int i = 1; i <= 41; i++ ) {
+// System.out.println( i + " => " + optimizer.generate( sequence ) + " (" + sequence.getCurrentValue() + ")" );
+// }
+// }
+//
+// public void testPooledDumping() {
+// int increment = 10;
+// SourceMock sequence = new SourceMock( 1, increment );
+// Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, increment );
+// for ( int i = 1; i <= 41; i++ ) {
+// System.out.println( i + " => " + optimizer.generate( sequence ) + " (" + sequence.getCurrentValue() + ")" );
+// }
+// }
+
+}
Copied: core/trunk/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java (from rev 19411, core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java)
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12 15:13:47 UTC (rev 19478)
@@ -0,0 +1,207 @@
+package org.hibernate.id.enhanced;
+
+import java.util.Properties;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.Hibernate;
+import org.hibernate.MappingException;
+import org.hibernate.cfg.ObjectNameNormalizer;
+import org.hibernate.cfg.NamingStrategy;
+
+/**
+ * Tests that SequenceStyleGenerator configures itself as expected
+ * in various scenarios
+ *
+ * @author Steve Ebersole
+ */
+@SuppressWarnings({ "deprecation" })
+public class SequenceStyleConfigUnitTest extends TestCase {
+ public SequenceStyleConfigUnitTest(String string) {
+ super( string );
+ }
+
+ public static Test suite() {
+ return new TestSuite( SequenceStyleConfigUnitTest.class );
+ }
+
+ private void assertClassAssignability(Class expected, Class actual) {
+ if ( ! expected.isAssignableFrom( actual ) ) {
+ fail( "Actual type [" + actual.getName() + "] is not assignable to expected type [" + expected.getName() + "]" );
+ }
+ }
+
+
+ /**
+ * Test all params defaulted with a dialect supporting sequences
+ */
+ public void testDefaultedSequenceBackedConfiguration() {
+ Dialect dialect = new SequenceDialect();
+ Properties props = buildGeneratorPropertiesBase();
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
+ assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ private Properties buildGeneratorPropertiesBase() {
+ Properties props = new Properties();
+ props.put(
+ PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
+ new ObjectNameNormalizer() {
+ protected boolean isUseQuotedIdentifiersGlobally() {
+ return false;
+ }
+
+ protected NamingStrategy getNamingStrategy() {
+ return null;
+ }
+ }
+ );
+ return props;
+ }
+
+ /**
+ * Test all params defaulted with a dialect which does not support sequences
+ */
+ public void testDefaultedTableBackedConfiguration() {
+ Dialect dialect = new TableDialect();
+ Properties props = buildGeneratorPropertiesBase();
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
+ assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ /**
+ * Test default optimizer selection for sequence backed generators
+ * based on the configured increment size; both in the case of the
+ * dialect supporting pooled sequences (pooled) and not (hilo)
+ */
+ public void testDefaultOptimizerBasedOnIncrementBackedBySequence() {
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
+
+ // for dialects which do not support pooled sequences, we default to pooled+table
+ Dialect dialect = new SequenceDialect();
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
+ assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+
+ // for dialects which do support pooled sequences, we default to pooled+sequence
+ dialect = new PooledSequenceDialect();
+ generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
+ assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ /**
+ * Test default optimizer selection for table backed generators
+ * based on the configured increment size. Here we always prefer
+ * pooled.
+ */
+ public void testDefaultOptimizerBasedOnIncrementBackedByTable() {
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
+ Dialect dialect = new TableDialect();
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
+ assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ /**
+ * Test forcing of table as backing strucuture with dialect supporting sequences
+ */
+ public void testForceTableUse() {
+ Dialect dialect = new SequenceDialect();
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.FORCE_TBL_PARAM, "true" );
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
+ assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ /**
+ * Test explicitly specifying both optimizer and increment
+ */
+ public void testExplicitOptimizerWithExplicitIncrementSize() {
+ // with sequence ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ final Dialect dialect = new SequenceDialect();
+
+ // optimizer=none w/ increment > 1 => should honor optimizer
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.NONE );
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
+ assertEquals( 1, generator.getOptimizer().getIncrementSize() );
+ assertEquals( 1, generator.getDatabaseStructure().getIncrementSize() );
+
+ // optimizer=hilo w/ increment > 1 => hilo
+ props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.HILO );
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
+ generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.HiLoOptimizer.class, generator.getOptimizer().getClass() );
+ assertEquals( 20, generator.getOptimizer().getIncrementSize() );
+ assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
+
+ // optimizer=pooled w/ increment > 1 => hilo
+ props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.POOL );
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
+ generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ // because the dialect reports to not support pooled seqyences, the expectation is that we will
+ // use a table for the backing structure...
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
+ assertEquals( 20, generator.getOptimizer().getIncrementSize() );
+ assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
+
+ }
+
+ private static class TableDialect extends Dialect {
+ public boolean supportsSequences() {
+ return false;
+ }
+ }
+
+ private static class SequenceDialect extends Dialect {
+ public boolean supportsSequences() {
+ return true;
+ }
+ public boolean supportsPooledSequences() {
+ return false;
+ }
+ public String getSequenceNextValString(String sequenceName) throws MappingException {
+ return "";
+ }
+ }
+
+ private static class PooledSequenceDialect extends SequenceDialect {
+ public boolean supportsPooledSequences() {
+ return true;
+ }
+ }
+}
Deleted: 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-05-12 15:13:03 UTC (rev 19477)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java 2010-05-12 15:13:47 UTC (rev 19478)
@@ -1,156 +0,0 @@
-package org.hibernate.test.idgen.enhanced;
-
-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;
-import org.hibernate.id.enhanced.AccessCallback;
-
-/**
- * {@inheritDoc}
- *
- * @author Steve Ebersole
- */
-public class OptimizerUnitTest extends UnitTestCase {
- public OptimizerUnitTest(String string) {
- super( string );
- }
-
- public static Test suite() {
- return new TestSuite( OptimizerUnitTest.class );
- }
-
- public void testBasicNoOptimizerUsage() {
- // test historic sequence behavior, where the initial values start at 1...
- SourceMock sequence = new SourceMock( 1 );
- Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
- for ( int i = 1; i < 11; i++ ) {
- final Long next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 10, sequence.getTimesCalled() );
- assertEquals( 10, sequence.getCurrentValue() );
-
- // test historic table behavior, where the initial values started at 0 (we now force 1 to be the first used id value)
- sequence = new SourceMock( 0 );
- optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
- for ( int i = 1; i < 11; i++ ) {
- final Long next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 11, sequence.getTimesCalled() ); // an extra time to get to 1 initially
- assertEquals( 10, sequence.getCurrentValue() );
- }
-
- public void testBasicHiLoOptimizerUsage() {
- int increment = 10;
- Long next;
-
- // test historic sequence behavior, where the initial values start at 1...
- SourceMock sequence = new SourceMock( 1 );
- Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
- for ( int i = 1; i <= increment; i++ ) {
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 1, sequence.getTimesCalled() ); // once to initialze state
- assertEquals( 1, sequence.getCurrentValue() );
- // force a "clock over"
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( 11, next.intValue() );
- assertEquals( 2, sequence.getTimesCalled() );
- assertEquals( 2, sequence.getCurrentValue() );
-
- // test historic table behavior, where the initial values started at 0 (we now force 1 to be the first used id value)
- sequence = new SourceMock( 0 );
- optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
- for ( int i = 1; i <= increment; i++ ) {
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 2, sequence.getTimesCalled() ); // here have have an extra call to get to 1 initially
- assertEquals( 1, sequence.getCurrentValue() );
- // force a "clock over"
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( 11, next.intValue() );
- assertEquals( 3, sequence.getTimesCalled() );
- assertEquals( 2, sequence.getCurrentValue() );
- }
-
- public void testBasicPooledOptimizerUsage() {
- Long next;
- // test historic sequence behavior, where the initial values start at 1...
- SourceMock sequence = new SourceMock( 1, 10 );
- Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 10 );
- for ( int i = 1; i < 11; i++ ) {
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 2, sequence.getTimesCalled() ); // twice to initialize state
- assertEquals( 11, sequence.getCurrentValue() );
- // force a "clock over"
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( 11, next.intValue() );
- assertEquals( 3, sequence.getTimesCalled() );
- assertEquals( 21, sequence.getCurrentValue() );
- }
-
- private static class SourceMock implements AccessCallback {
- private IdentifierGeneratorHelper.BasicHolder value = new IdentifierGeneratorHelper.BasicHolder( Long.class );
- private int increment;
- private int timesCalled = 0;
-
- public SourceMock(long initialValue) {
- this( initialValue, 1 );
- }
-
- public SourceMock(long initialValue, int increment) {
- this.increment = increment;
- this.value.initialize( initialValue - increment );
- }
-
- public IntegralDataTypeHolder getNextValue() {
- timesCalled++;
- return value.add( increment ).copy();
- }
-
- public int getTimesCalled() {
- return timesCalled;
- }
-
- public long getCurrentValue() {
- return value.getActualLongValue();
- }
- }
-
-// public void testNoopDumping() {
-// SourceMock sequence = new SourceMock( 1 );
-// Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
-// for ( int i = 1; i <= 41; i++ ) {
-// System.out.println( i + " => " + optimizer.generate( sequence ) + " (" + sequence.getCurrentValue() + ")" );
-// }
-// }
-//
-// public void testHiLoDumping() {
-// int increment = 10;
-// SourceMock sequence = new SourceMock( 1 );
-// Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
-// for ( int i = 1; i <= 41; i++ ) {
-// System.out.println( i + " => " + optimizer.generate( sequence ) + " (" + sequence.getCurrentValue() + ")" );
-// }
-// }
-//
-// public void testPooledDumping() {
-// int increment = 10;
-// SourceMock sequence = new SourceMock( 1, increment );
-// Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, increment );
-// for ( int i = 1; i <= 41; i++ ) {
-// System.out.println( i + " => " + optimizer.generate( sequence ) + " (" + sequence.getCurrentValue() + ")" );
-// }
-// }
-
-}
Deleted: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12 15:13:03 UTC (rev 19477)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12 15:13:47 UTC (rev 19478)
@@ -1,203 +0,0 @@
-package org.hibernate.test.idgen.enhanced;
-
-import java.util.Properties;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import org.hibernate.junit.UnitTestCase;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.id.enhanced.SequenceStyleGenerator;
-import org.hibernate.id.enhanced.SequenceStructure;
-import org.hibernate.id.enhanced.OptimizerFactory;
-import org.hibernate.id.enhanced.TableStructure;
-import org.hibernate.id.PersistentIdentifierGenerator;
-import org.hibernate.Hibernate;
-import org.hibernate.MappingException;
-import org.hibernate.cfg.ObjectNameNormalizer;
-import org.hibernate.cfg.NamingStrategy;
-
-/**
- * Tests that SequenceStyleGenerator configures itself as expected
- * in various scenarios
- *
- * @author Steve Ebersole
- */
-public class SequenceStyleConfigUnitTest extends UnitTestCase {
- public SequenceStyleConfigUnitTest(String string) {
- super( string );
- }
-
- public static Test suite() {
- return new TestSuite( SequenceStyleConfigUnitTest.class );
- }
-
- /**
- * Test all params defaulted with a dialect supporting sequences
- */
- public void testDefaultedSequenceBackedConfiguration() {
- Dialect dialect = new SequenceDialect();
- Properties props = buildGeneratorPropertiesBase();
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
-
- assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- private Properties buildGeneratorPropertiesBase() {
- Properties props = new Properties();
- props.put(
- PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
- new ObjectNameNormalizer() {
- protected boolean isUseQuotedIdentifiersGlobally() {
- return false;
- }
-
- protected NamingStrategy getNamingStrategy() {
- return null;
- }
- }
- );
- return props;
- }
-
- /**
- * Test all params defaulted with a dialect which does not support sequences
- */
- public void testDefaultedTableBackedConfiguration() {
- Dialect dialect = new TableDialect();
- Properties props = buildGeneratorPropertiesBase();
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
-
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- /**
- * Test default optimizer selection for sequence backed generators
- * based on the configured increment size; both in the case of the
- * dialect supporting pooled sequences (pooled) and not (hilo)
- */
- public void testDefaultOptimizerBasedOnIncrementBackedBySequence() {
- Properties props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
-
- // for dialects which do not support pooled sequences, we default to pooled+table
- Dialect dialect = new SequenceDialect();
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
-
- // for dialects which do support pooled sequences, we default to pooled+sequence
- dialect = new PooledSequenceDialect();
- generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- /**
- * Test default optimizer selection for table backed generators
- * based on the configured increment size. Here we always prefer
- * pooled.
- */
- public void testDefaultOptimizerBasedOnIncrementBackedByTable() {
- Properties props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
- Dialect dialect = new TableDialect();
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- /**
- * Test forcing of table as backing strucuture with dialect supporting sequences
- */
- public void testForceTableUse() {
- Dialect dialect = new SequenceDialect();
- Properties props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.FORCE_TBL_PARAM, "true" );
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- /**
- * Test explicitly specifying both optimizer and increment
- */
- public void testExplicitOptimizerWithExplicitIncrementSize() {
- // with sequence ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- final Dialect dialect = new SequenceDialect();
-
- // optimizer=none w/ increment > 1 => should honor optimizer
- Properties props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.NONE );
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( 1, generator.getOptimizer().getIncrementSize() );
- assertEquals( 1, generator.getDatabaseStructure().getIncrementSize() );
-
- // optimizer=hilo w/ increment > 1 => hilo
- props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.HILO );
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
- generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.HiLoOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( 20, generator.getOptimizer().getIncrementSize() );
- assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
-
- // optimizer=pooled w/ increment > 1 => hilo
- props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.POOL );
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
- generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- // because the dialect reports to not support pooled seqyences, the expectation is that we will
- // use a table for the backing structure...
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( 20, generator.getOptimizer().getIncrementSize() );
- assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
-
- }
-
- private static class TableDialect extends Dialect {
- public boolean supportsSequences() {
- return false;
- }
- }
-
- private static class SequenceDialect extends Dialect {
- public boolean supportsSequences() {
- return true;
- }
- public boolean supportsPooledSequences() {
- return false;
- }
- public String getSequenceNextValString(String sequenceName) throws MappingException {
- return "";
- }
- }
-
- private static class PooledSequenceDialect extends SequenceDialect {
- public boolean supportsPooledSequences() {
- return true;
- }
- }
-}
14 years, 8 months
Hibernate SVN: r19477 - in core/branches/Branch_3_5: core/src/test/java/org/hibernate/id and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2010-05-12 11:13:03 -0400 (Wed, 12 May 2010)
New Revision: 19477
Added:
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java
core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java
Removed:
core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java
core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java
Modified:
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
Log:
HHH-5217 - Minimize double sequence value reads in PooledOptimizer
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2010-05-12 14:46:34 UTC (rev 19476)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2010-05-12 15:13:03 UTC (rev 19477)
@@ -44,10 +44,40 @@
public static final String NONE = "none";
public static final String HILO = "hilo";
+ public static final String LEGACY_HILO = "legacy-hilo";
public static final String POOL = "pooled";
private static Class[] CTOR_SIG = new Class[] { Class.class, int.class };
+ /**
+ * Marker interface for optimizer which wish to know the user-specified initial value.
+ * <p/>
+ * Used instead of constructor injection since that is already a public understanding and
+ * because not all optimizers care.
+ */
+ public static interface InitialValueAwareOptimizer {
+ /**
+ * Reports the user specified initial value to the optimizer.
+ * <p/>
+ * <tt>-1</tt> is used to indicate that the user did not specify.
+ *
+ * @param initialValue The initial value specified by the user, or <tt>-1</tt> to indicate that the
+ * user did not specify.
+ */
+ public void injectInitialValue(long initialValue);
+ }
+
+ /**
+ * Builds an optimizer
+ *
+ * @param type The optimizer type, either a short-hand name or the {@link Optimizer} class name.
+ * @param returnClass The generated value java type
+ * @param incrementSize The increment size.
+ *
+ * @return The built optimizer
+ *
+ * @deprecated Use {@link #buildOptimizer(String, Class, int, long)} instead
+ */
public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize) {
String optimizerClassName;
if ( NONE.equals( type ) ) {
@@ -56,6 +86,9 @@
else if ( HILO.equals( type ) ) {
optimizerClassName = HiLoOptimizer.class.getName();
}
+ else if ( LEGACY_HILO.equals( type ) ) {
+ optimizerClassName = LegacyHiLoAlgorithmOptimizer.class.getName();
+ }
else if ( POOL.equals( type ) ) {
optimizerClassName = PooledOptimizer.class.getName();
}
@@ -76,7 +109,27 @@
return new NoopOptimizer( returnClass, incrementSize );
}
+
/**
+ * Builds an optimizer
+ *
+ * @param type The optimizer type, either a short-hand name or the {@link Optimizer} class name.
+ * @param returnClass The generated value java type
+ * @param incrementSize The increment size.
+ * @param explicitInitialValue The user supplied initial-value (-1 indicates the user did not specify).
+ *
+ * @return The built optimizer
+ */
+ public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize, long explicitInitialValue) {
+ //noinspection deprecation
+ final Optimizer optimizer = buildOptimizer( type, returnClass, incrementSize );
+ if ( InitialValueAwareOptimizer.class.isInstance( optimizer ) ) {
+ ( (InitialValueAwareOptimizer) optimizer ).injectInitialValue( explicitInitialValue );
+ }
+ return optimizer;
+ }
+
+ /**
* Common support for optimizer implementations.
*/
public static abstract class OptimizerSupport implements Optimizer {
@@ -334,9 +387,10 @@
* {@link HiLoOptimizer} except that here the bucket ranges are actually
* encoded into the database structures.
*/
- public static class PooledOptimizer extends OptimizerSupport {
+ public static class PooledOptimizer extends OptimizerSupport implements InitialValueAwareOptimizer {
private IntegralDataTypeHolder hiValue;
private IntegralDataTypeHolder value;
+ private long initialValue = -1;
public PooledOptimizer(Class returnClass, int incrementSize) {
super( returnClass, incrementSize );
@@ -361,7 +415,14 @@
// we are using a sequence...
log.info( "pooled optimizer source reported [" + value + "] as the initial value; use of 1 or greater highly recommended" );
}
- hiValue = callback.getNextValue();
+ if ( ( initialValue == -1 && value.lt( incrementSize ) ) || value.eq( initialValue ) ) {
+ // the call to obtain next-value just gave us the initialValue
+ hiValue = callback.getNextValue();
+ }
+ else {
+ hiValue = value;
+ value = hiValue.copy().subtract( incrementSize );
+ }
}
else if ( ! hiValue.gt( value ) ) {
hiValue = callback.getNextValue();
@@ -394,5 +455,12 @@
public IntegralDataTypeHolder getLastValue() {
return value.copy().decrement();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void injectInitialValue(long initialValue) {
+ this.initialValue = initialValue;
+ }
}
}
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java 2010-05-12 14:46:34 UTC (rev 19476)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java 2010-05-12 15:13:03 UTC (rev 19477)
@@ -187,8 +187,12 @@
initialValue,
incrementSize
);
-
- this.optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
+ this.optimizer = OptimizerFactory.buildOptimizer(
+ optimizationStrategy,
+ identifierType.getReturnedClass(),
+ incrementSize,
+ PropertiesHelper.getInt( INITIAL_PARAM, params, -1 )
+ );
this.databaseStructure.prepare( optimizer );
}
@@ -305,7 +309,9 @@
* @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 An abstraction for the actual database structure in use (table vs. sequence).
*/
protected DatabaseStructure buildDatabaseStructure(
Type type,
Modified: core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
===================================================================
--- core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java 2010-05-12 14:46:34 UTC (rev 19476)
+++ core/branches/Branch_3_5/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java 2010-05-12 15:13:03 UTC (rev 19477)
@@ -305,7 +305,12 @@
String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
- optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
+ optimizer = OptimizerFactory.buildOptimizer(
+ optimizationStrategy,
+ identifierType.getReturnedClass(),
+ incrementSize,
+ PropertiesHelper.getInt( INITIAL_PARAM, params, -1 )
+ );
}
/**
@@ -430,8 +435,8 @@
String query = "select " + StringHelper.qualify( alias, valueColumnName ) +
" from " + tableName + ' ' + alias +
" where " + StringHelper.qualify( alias, segmentColumnName ) + "=?";
- LockOptions lockOptions = new LockOptions(LockMode.UPGRADE);
- lockOptions.setAliasSpecificLockMode( alias, LockMode.UPGRADE );
+ LockOptions lockOptions = new LockOptions( LockMode.PESSIMISTIC_WRITE );
+ lockOptions.setAliasSpecificLockMode( alias, LockMode.PESSIMISTIC_WRITE );
Map updateTargetColumnsMap = Collections.singletonMap( alias, new String[] { valueColumnName } );
return dialect.applyLocksToSql( query, lockOptions, updateTargetColumnsMap );
}
Copied: core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java (from rev 19465, core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java)
===================================================================
--- core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java (rev 0)
+++ core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/OptimizerUnitTest.java 2010-05-12 15:13:03 UTC (rev 19477)
@@ -0,0 +1,186 @@
+package org.hibernate.id.enhanced;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.hibernate.id.IdentifierGeneratorHelper;
+import org.hibernate.id.IntegralDataTypeHolder;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class OptimizerUnitTest extends TestCase {
+ public OptimizerUnitTest(String string) {
+ super( string );
+ }
+
+ public static Test suite() {
+ return new TestSuite( OptimizerUnitTest.class );
+ }
+
+ public void testBasicNoOptimizerUsage() {
+ // test historic sequence behavior, where the initial values start at 1...
+ SourceMock sequence = new SourceMock( 1 );
+ Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
+ for ( int i = 1; i < 11; i++ ) {
+ final Long next = ( Long ) optimizer.generate( sequence );
+ Assert.assertEquals( i, next.intValue() );
+ }
+ Assert.assertEquals( 10, sequence.getTimesCalled() );
+ Assert.assertEquals( 10, sequence.getCurrentValue() );
+
+ // test historic table behavior, where the initial values started at 0 (we now force 1 to be the first used id value)
+ sequence = new SourceMock( 0 );
+ optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
+ for ( int i = 1; i < 11; i++ ) {
+ final Long next = ( Long ) optimizer.generate( sequence );
+ Assert.assertEquals( i, next.intValue() );
+ }
+ Assert.assertEquals( 11, sequence.getTimesCalled() ); // an extra time to get to 1 initially
+ Assert.assertEquals( 10, sequence.getCurrentValue() );
+ }
+
+ public void testBasicHiLoOptimizerUsage() {
+ int increment = 10;
+ Long next;
+
+ // test historic sequence behavior, where the initial values start at 1...
+ SourceMock sequence = new SourceMock( 1 );
+ Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
+ for ( int i = 1; i <= increment; i++ ) {
+ next = ( Long ) optimizer.generate( sequence );
+ Assert.assertEquals( i, next.intValue() );
+ }
+ Assert.assertEquals( 1, sequence.getTimesCalled() ); // once to initialze state
+ Assert.assertEquals( 1, sequence.getCurrentValue() );
+ // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ Assert.assertEquals( 11, next.intValue() );
+ Assert.assertEquals( 2, sequence.getTimesCalled() );
+ Assert.assertEquals( 2, sequence.getCurrentValue() );
+
+ // test historic table behavior, where the initial values started at 0 (we now force 1 to be the first used id value)
+ sequence = new SourceMock( 0 );
+ optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
+ for ( int i = 1; i <= increment; i++ ) {
+ next = ( Long ) optimizer.generate( sequence );
+ Assert.assertEquals( i, next.intValue() );
+ }
+ Assert.assertEquals( 2, sequence.getTimesCalled() ); // here have have an extra call to get to 1 initially
+ Assert.assertEquals( 1, sequence.getCurrentValue() );
+ // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ Assert.assertEquals( 11, next.intValue() );
+ Assert.assertEquals( 3, sequence.getTimesCalled() );
+ Assert.assertEquals( 2, sequence.getCurrentValue() );
+ }
+
+ public void testBasicPooledOptimizerUsage() {
+ Long next;
+ // test historic sequence behavior, where the initial values start at 1...
+ SourceMock sequence = new SourceMock( 1, 10 );
+ Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 10 );
+ for ( int i = 1; i < 11; i++ ) {
+ next = ( Long ) optimizer.generate( sequence );
+ Assert.assertEquals( i, next.intValue() );
+ }
+ Assert.assertEquals( 2, sequence.getTimesCalled() ); // twice to initialize state
+ Assert.assertEquals( 11, sequence.getCurrentValue() );
+ // force a "clock over"
+ next = ( Long ) optimizer.generate( sequence );
+ Assert.assertEquals( 11, next.intValue() );
+ Assert.assertEquals( 3, sequence.getTimesCalled() );
+ Assert.assertEquals( 21, sequence.getCurrentValue() );
+ }
+
+ public void testSubsequentPooledOptimizerUsage() {
+ // test the pooled optimizer in situation where the sequence is already beyond its initial value on init.
+ // cheat by telling the sequence to start with 1000
+ final SourceMock sequence = new SourceMock( 1000, 3, 5 );
+ // but tell the optimizer the start-with is 1
+ final Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 3, 1 );
+
+ assertEquals( 5, sequence.getTimesCalled() );
+ assertEquals( 1000, sequence.getCurrentValue() );
+
+ Long next = (Long) optimizer.generate( sequence );
+ assertEquals( 1000, next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1000+3), sequence.getCurrentValue() );
+
+ next = (Long) optimizer.generate( sequence );
+ assertEquals( 1001, next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1000+3), sequence.getCurrentValue() );
+
+ next = (Long) optimizer.generate( sequence );
+ assertEquals( 1002, next.intValue() );
+ assertEquals( (5+1), sequence.getTimesCalled() );
+ assertEquals( (1000+3), sequence.getCurrentValue() );
+
+ // force a "clock over"
+ next = (Long) optimizer.generate( sequence );
+ assertEquals( 1003, next.intValue() );
+ assertEquals( (5+2), sequence.getTimesCalled() );
+ assertEquals( (1000+6), sequence.getCurrentValue() );
+ }
+
+ private static class SourceMock implements AccessCallback {
+ private IdentifierGeneratorHelper.BasicHolder value = new IdentifierGeneratorHelper.BasicHolder( Long.class );
+ private long initialValue;
+ private int increment;
+ private int timesCalled = 0;
+
+ public SourceMock(long initialValue) {
+ this( initialValue, 1 );
+ }
+
+ public SourceMock(long initialValue, int increment) {
+ this( initialValue, increment, 0 );
+ }
+
+ public SourceMock(long initialValue, int increment, int timesCalled) {
+ this.increment = increment;
+ this.timesCalled = timesCalled;
+ if ( timesCalled != 0 ) {
+ this.value.initialize( initialValue );
+ this.initialValue = 1;
+ }
+ else {
+ this.initialValue = initialValue;
+ }
+ }
+
+ public IntegralDataTypeHolder getNextValue() {
+ try {
+ if ( timesCalled == 0 ) {
+ initValue();
+ return value.copy();
+ }
+ else {
+ return value.add( increment ).copy();
+ }
+ }
+ finally {
+ timesCalled++;
+ }
+ }
+
+ private void initValue() {
+ this.value.initialize( initialValue );
+ }
+
+ public int getTimesCalled() {
+ return timesCalled;
+ }
+
+ public long getCurrentValue() {
+ return value == null ? -1 : value.getActualLongValue();
+ }
+ }
+
+}
Copied: core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java (from rev 19465, core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java)
===================================================================
--- core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java (rev 0)
+++ core/branches/Branch_3_5/core/src/test/java/org/hibernate/id/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12 15:13:03 UTC (rev 19477)
@@ -0,0 +1,208 @@
+package org.hibernate.id.enhanced;
+
+import java.util.Properties;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.hibernate.Hibernate;
+import org.hibernate.MappingException;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.cfg.ObjectNameNormalizer;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.id.PersistentIdentifierGenerator;
+
+/**
+ * Tests that SequenceStyleGenerator configures itself as expected
+ * in various scenarios
+ *
+ * @author Steve Ebersole
+ * @noinspection deprecation
+ */
+public class SequenceStyleConfigUnitTest extends TestCase {
+ public SequenceStyleConfigUnitTest(String string) {
+ super( string );
+ }
+
+ public static Test suite() {
+ return new TestSuite( SequenceStyleConfigUnitTest.class );
+ }
+
+
+ private void assertClassAssignability(Class expected, Class actual) {
+ if ( ! expected.isAssignableFrom( actual ) ) {
+ fail( "Actual type [" + actual.getName() + "] is not assignable to expected type [" + expected.getName() + "]" );
+ }
+ }
+
+ /**
+ * Test all params defaulted with a dialect supporting sequences
+ */
+ public void testDefaultedSequenceBackedConfiguration() {
+ Dialect dialect = new SequenceDialect();
+ Properties props = buildGeneratorPropertiesBase();
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
+ Assert.assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ private Properties buildGeneratorPropertiesBase() {
+ Properties props = new Properties();
+ props.put(
+ PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
+ new ObjectNameNormalizer() {
+ protected boolean isUseQuotedIdentifiersGlobally() {
+ return false;
+ }
+
+ protected NamingStrategy getNamingStrategy() {
+ return null;
+ }
+ }
+ );
+ return props;
+ }
+
+ /**
+ * Test all params defaulted with a dialect which does not support sequences
+ */
+ public void testDefaultedTableBackedConfiguration() {
+ Dialect dialect = new TableDialect();
+ Properties props = buildGeneratorPropertiesBase();
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
+ Assert.assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ /**
+ * Test default optimizer selection for sequence backed generators
+ * based on the configured increment size; both in the case of the
+ * dialect supporting pooled sequences (pooled) and not (hilo)
+ */
+ public void testDefaultOptimizerBasedOnIncrementBackedBySequence() {
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
+
+ // for dialects which do not support pooled sequences, we default to pooled+table
+ Dialect dialect = new SequenceDialect();
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
+ Assert.assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+
+ // for dialects which do support pooled sequences, we default to pooled+sequence
+ dialect = new PooledSequenceDialect();
+ generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
+ Assert.assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ /**
+ * Test default optimizer selection for table backed generators
+ * based on the configured increment size. Here we always prefer
+ * pooled.
+ */
+ public void testDefaultOptimizerBasedOnIncrementBackedByTable() {
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
+ Dialect dialect = new TableDialect();
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
+ Assert.assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ /**
+ * Test forcing of table as backing strucuture with dialect supporting sequences
+ */
+ public void testForceTableUse() {
+ Dialect dialect = new SequenceDialect();
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.FORCE_TBL_PARAM, "true" );
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
+ Assert.assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
+ }
+
+ /**
+ * Test explicitly specifying both optimizer and increment
+ */
+ public void testExplicitOptimizerWithExplicitIncrementSize() {
+ // with sequence ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ final Dialect dialect = new SequenceDialect();
+
+ // optimizer=none w/ increment > 1 => should honor optimizer
+ Properties props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.NONE );
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
+ SequenceStyleGenerator generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
+ Assert.assertEquals( 1, generator.getOptimizer().getIncrementSize() );
+ Assert.assertEquals( 1, generator.getDatabaseStructure().getIncrementSize() );
+
+ // optimizer=hilo w/ increment > 1 => hilo
+ props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.HILO );
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
+ generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.HiLoOptimizer.class, generator.getOptimizer().getClass() );
+ Assert.assertEquals( 20, generator.getOptimizer().getIncrementSize() );
+ Assert.assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
+
+ // optimizer=pooled w/ increment > 1 => hilo
+ props = buildGeneratorPropertiesBase();
+ props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.POOL );
+ props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
+ generator = new SequenceStyleGenerator();
+ generator.configure( Hibernate.LONG, props, dialect );
+ // because the dialect reports to not support pooled seqyences, the expectation is that we will
+ // use a table for the backing structure...
+ assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
+ assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
+ Assert.assertEquals( 20, generator.getOptimizer().getIncrementSize() );
+ Assert.assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
+
+ }
+
+ private static class TableDialect extends Dialect {
+ public boolean supportsSequences() {
+ return false;
+ }
+ }
+
+ private static class SequenceDialect extends Dialect {
+ public boolean supportsSequences() {
+ return true;
+ }
+ public boolean supportsPooledSequences() {
+ return false;
+ }
+ public String getSequenceNextValString(String sequenceName) throws MappingException {
+ return "";
+ }
+ }
+
+ private static class PooledSequenceDialect extends SequenceDialect {
+ public boolean supportsPooledSequences() {
+ return true;
+ }
+ }
+}
Deleted: core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java
===================================================================
--- core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java 2010-05-12 14:46:34 UTC (rev 19476)
+++ core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/OptimizerUnitTest.java 2010-05-12 15:13:03 UTC (rev 19477)
@@ -1,156 +0,0 @@
-package org.hibernate.test.idgen.enhanced;
-
-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;
-import org.hibernate.id.enhanced.AccessCallback;
-
-/**
- * {@inheritDoc}
- *
- * @author Steve Ebersole
- */
-public class OptimizerUnitTest extends UnitTestCase {
- public OptimizerUnitTest(String string) {
- super( string );
- }
-
- public static Test suite() {
- return new TestSuite( OptimizerUnitTest.class );
- }
-
- public void testBasicNoOptimizerUsage() {
- // test historic sequence behavior, where the initial values start at 1...
- SourceMock sequence = new SourceMock( 1 );
- Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
- for ( int i = 1; i < 11; i++ ) {
- final Long next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 10, sequence.getTimesCalled() );
- assertEquals( 10, sequence.getCurrentValue() );
-
- // test historic table behavior, where the initial values started at 0 (we now force 1 to be the first used id value)
- sequence = new SourceMock( 0 );
- optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
- for ( int i = 1; i < 11; i++ ) {
- final Long next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 11, sequence.getTimesCalled() ); // an extra time to get to 1 initially
- assertEquals( 10, sequence.getCurrentValue() );
- }
-
- public void testBasicHiLoOptimizerUsage() {
- int increment = 10;
- Long next;
-
- // test historic sequence behavior, where the initial values start at 1...
- SourceMock sequence = new SourceMock( 1 );
- Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
- for ( int i = 1; i <= increment; i++ ) {
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 1, sequence.getTimesCalled() ); // once to initialze state
- assertEquals( 1, sequence.getCurrentValue() );
- // force a "clock over"
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( 11, next.intValue() );
- assertEquals( 2, sequence.getTimesCalled() );
- assertEquals( 2, sequence.getCurrentValue() );
-
- // test historic table behavior, where the initial values started at 0 (we now force 1 to be the first used id value)
- sequence = new SourceMock( 0 );
- optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
- for ( int i = 1; i <= increment; i++ ) {
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 2, sequence.getTimesCalled() ); // here have have an extra call to get to 1 initially
- assertEquals( 1, sequence.getCurrentValue() );
- // force a "clock over"
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( 11, next.intValue() );
- assertEquals( 3, sequence.getTimesCalled() );
- assertEquals( 2, sequence.getCurrentValue() );
- }
-
- public void testBasicPooledOptimizerUsage() {
- Long next;
- // test historic sequence behavior, where the initial values start at 1...
- SourceMock sequence = new SourceMock( 1, 10 );
- Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, 10 );
- for ( int i = 1; i < 11; i++ ) {
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( i, next.intValue() );
- }
- assertEquals( 2, sequence.getTimesCalled() ); // twice to initialize state
- assertEquals( 11, sequence.getCurrentValue() );
- // force a "clock over"
- next = ( Long ) optimizer.generate( sequence );
- assertEquals( 11, next.intValue() );
- assertEquals( 3, sequence.getTimesCalled() );
- assertEquals( 21, sequence.getCurrentValue() );
- }
-
- private static class SourceMock implements AccessCallback {
- private IdentifierGeneratorHelper.BasicHolder value = new IdentifierGeneratorHelper.BasicHolder( Long.class );
- private int increment;
- private int timesCalled = 0;
-
- public SourceMock(long initialValue) {
- this( initialValue, 1 );
- }
-
- public SourceMock(long initialValue, int increment) {
- this.increment = increment;
- this.value.initialize( initialValue - increment );
- }
-
- public IntegralDataTypeHolder getNextValue() {
- timesCalled++;
- return value.add( increment ).copy();
- }
-
- public int getTimesCalled() {
- return timesCalled;
- }
-
- public long getCurrentValue() {
- return value.getActualLongValue();
- }
- }
-
-// public void testNoopDumping() {
-// SourceMock sequence = new SourceMock( 1 );
-// Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.NONE, Long.class, 1 );
-// for ( int i = 1; i <= 41; i++ ) {
-// System.out.println( i + " => " + optimizer.generate( sequence ) + " (" + sequence.getCurrentValue() + ")" );
-// }
-// }
-//
-// public void testHiLoDumping() {
-// int increment = 10;
-// SourceMock sequence = new SourceMock( 1 );
-// Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.HILO, Long.class, increment );
-// for ( int i = 1; i <= 41; i++ ) {
-// System.out.println( i + " => " + optimizer.generate( sequence ) + " (" + sequence.getCurrentValue() + ")" );
-// }
-// }
-//
-// public void testPooledDumping() {
-// int increment = 10;
-// SourceMock sequence = new SourceMock( 1, increment );
-// Optimizer optimizer = OptimizerFactory.buildOptimizer( OptimizerFactory.POOL, Long.class, increment );
-// for ( int i = 1; i <= 41; i++ ) {
-// System.out.println( i + " => " + optimizer.generate( sequence ) + " (" + sequence.getCurrentValue() + ")" );
-// }
-// }
-
-}
Deleted: core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java
===================================================================
--- core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12 14:46:34 UTC (rev 19476)
+++ core/branches/Branch_3_5/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/SequenceStyleConfigUnitTest.java 2010-05-12 15:13:03 UTC (rev 19477)
@@ -1,203 +0,0 @@
-package org.hibernate.test.idgen.enhanced;
-
-import java.util.Properties;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import org.hibernate.junit.UnitTestCase;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.id.enhanced.SequenceStyleGenerator;
-import org.hibernate.id.enhanced.SequenceStructure;
-import org.hibernate.id.enhanced.OptimizerFactory;
-import org.hibernate.id.enhanced.TableStructure;
-import org.hibernate.id.PersistentIdentifierGenerator;
-import org.hibernate.Hibernate;
-import org.hibernate.MappingException;
-import org.hibernate.cfg.ObjectNameNormalizer;
-import org.hibernate.cfg.NamingStrategy;
-
-/**
- * Tests that SequenceStyleGenerator configures itself as expected
- * in various scenarios
- *
- * @author Steve Ebersole
- */
-public class SequenceStyleConfigUnitTest extends UnitTestCase {
- public SequenceStyleConfigUnitTest(String string) {
- super( string );
- }
-
- public static Test suite() {
- return new TestSuite( SequenceStyleConfigUnitTest.class );
- }
-
- /**
- * Test all params defaulted with a dialect supporting sequences
- */
- public void testDefaultedSequenceBackedConfiguration() {
- Dialect dialect = new SequenceDialect();
- Properties props = buildGeneratorPropertiesBase();
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
-
- assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- private Properties buildGeneratorPropertiesBase() {
- Properties props = new Properties();
- props.put(
- PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
- new ObjectNameNormalizer() {
- protected boolean isUseQuotedIdentifiersGlobally() {
- return false;
- }
-
- protected NamingStrategy getNamingStrategy() {
- return null;
- }
- }
- );
- return props;
- }
-
- /**
- * Test all params defaulted with a dialect which does not support sequences
- */
- public void testDefaultedTableBackedConfiguration() {
- Dialect dialect = new TableDialect();
- Properties props = buildGeneratorPropertiesBase();
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
-
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- /**
- * Test default optimizer selection for sequence backed generators
- * based on the configured increment size; both in the case of the
- * dialect supporting pooled sequences (pooled) and not (hilo)
- */
- public void testDefaultOptimizerBasedOnIncrementBackedBySequence() {
- Properties props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
-
- // for dialects which do not support pooled sequences, we default to pooled+table
- Dialect dialect = new SequenceDialect();
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
-
- // for dialects which do support pooled sequences, we default to pooled+sequence
- dialect = new PooledSequenceDialect();
- generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- /**
- * Test default optimizer selection for table backed generators
- * based on the configured increment size. Here we always prefer
- * pooled.
- */
- public void testDefaultOptimizerBasedOnIncrementBackedByTable() {
- Properties props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
- Dialect dialect = new TableDialect();
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- /**
- * Test forcing of table as backing strucuture with dialect supporting sequences
- */
- public void testForceTableUse() {
- Dialect dialect = new SequenceDialect();
- Properties props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.FORCE_TBL_PARAM, "true" );
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
- }
-
- /**
- * Test explicitly specifying both optimizer and increment
- */
- public void testExplicitOptimizerWithExplicitIncrementSize() {
- // with sequence ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- final Dialect dialect = new SequenceDialect();
-
- // optimizer=none w/ increment > 1 => should honor optimizer
- Properties props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.NONE );
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
- SequenceStyleGenerator generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( 1, generator.getOptimizer().getIncrementSize() );
- assertEquals( 1, generator.getDatabaseStructure().getIncrementSize() );
-
- // optimizer=hilo w/ increment > 1 => hilo
- props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.HILO );
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
- generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.HiLoOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( 20, generator.getOptimizer().getIncrementSize() );
- assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
-
- // optimizer=pooled w/ increment > 1 => hilo
- props = buildGeneratorPropertiesBase();
- props.setProperty( SequenceStyleGenerator.OPT_PARAM, OptimizerFactory.POOL );
- props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
- generator = new SequenceStyleGenerator();
- generator.configure( Hibernate.LONG, props, dialect );
- // because the dialect reports to not support pooled seqyences, the expectation is that we will
- // use a table for the backing structure...
- assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
- assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
- assertEquals( 20, generator.getOptimizer().getIncrementSize() );
- assertEquals( 20, generator.getDatabaseStructure().getIncrementSize() );
-
- }
-
- private static class TableDialect extends Dialect {
- public boolean supportsSequences() {
- return false;
- }
- }
-
- private static class SequenceDialect extends Dialect {
- public boolean supportsSequences() {
- return true;
- }
- public boolean supportsPooledSequences() {
- return false;
- }
- public String getSequenceNextValString(String sequenceName) throws MappingException {
- return "";
- }
- }
-
- private static class PooledSequenceDialect extends SequenceDialect {
- public boolean supportsPooledSequences() {
- return true;
- }
- }
-}
14 years, 8 months
Hibernate SVN: r19476 - core/branches/Branch_3_3_2_GA_CP/parent.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-05-12 10:46:34 -0400 (Wed, 12 May 2010)
New Revision: 19476
Modified:
core/branches/Branch_3_3_2_GA_CP/parent/pom.xml
Log:
JBPAPP-4253 update db driver version
Modified: core/branches/Branch_3_3_2_GA_CP/parent/pom.xml
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/parent/pom.xml 2010-05-12 12:42:31 UTC (rev 19475)
+++ core/branches/Branch_3_3_2_GA_CP/parent/pom.xml 2010-05-12 14:46:34 UTC (rev 19476)
@@ -459,7 +459,7 @@
<!-- The MySQL5 test envionment -->
<profile>
- <id>mysql50</id>
+ <id>mysql5</id>
<dependencies>
<dependency>
<groupId>mysql</groupId>
@@ -499,7 +499,7 @@
<!-- The PostgreSQL 8.2.4 test envionment -->
<profile>
- <id>postgresql82</id>
+ <id>postgresql824</id>
<dependencies>
<dependency>
<groupId>postgresql</groupId>
@@ -521,7 +521,7 @@
<!-- The PostgreSQL 8.3.7 test envionment -->
<profile>
- <id>postgresql83</id>
+ <id>postgresql837</id>
<dependencies>
<dependency>
<groupId>postgresql</groupId>
@@ -549,7 +549,7 @@
<!-- The DB2 9.7 test envionment (using 9x drivers)-->
<profile>
- <id>db2-97</id>
+ <id>db2v97</id>
<dependencies>
<dependency>
<groupId>com.ibm</groupId>
@@ -575,7 +575,7 @@
<!-- The DB2 9.x test envionment (using 9x drivers)-->
<profile>
- <id>db2-91</id>
+ <id>db2v91</id>
<dependencies>
<dependency>
<groupId>com.ibm</groupId>
14 years, 8 months
Hibernate SVN: r19475 - core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/schemaupdate.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-05-12 08:42:31 -0400 (Wed, 12 May 2010)
New Revision: 19475
Modified:
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/schemaupdate/MigrationTest.java
Log:
drop table after test
Modified: core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/schemaupdate/MigrationTest.java
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/schemaupdate/MigrationTest.java 2010-05-12 11:03:46 UTC (rev 19474)
+++ core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/schemaupdate/MigrationTest.java 2010-05-12 12:42:31 UTC (rev 19475)
@@ -40,7 +40,7 @@
SchemaUpdate v2schemaUpdate = new SchemaUpdate( v2cfg );
v2schemaUpdate.execute( true, true );
assertEquals( 0, v2schemaUpdate.getExceptions().size() );
-
+ new SchemaExport( v2cfg ).execute( false, true, true, false );
}
}
14 years, 8 months
Hibernate SVN: r19474 - search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality.
by hibernate-commits@lists.jboss.org
Author: stliu
Date: 2010-05-12 07:03:46 -0400 (Wed, 12 May 2010)
New Revision: 19474
Added:
search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/MockIndexReader.java
search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/TestManipulatorPerDP.java
Modified:
search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/SharingBufferIndexProviderTest.java
search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/TestableSharingBufferReaderProvider.java
Log:
JBPAPP-2289 HSEARCH unit test failure: org.hibernate.search.test.reader.functionality.TestableSharingBufferReaderProvider
Added: search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/MockIndexReader.java
===================================================================
--- search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/MockIndexReader.java (rev 0)
+++ search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/MockIndexReader.java 2010-05-12 11:03:46 UTC (rev 19474)
@@ -0,0 +1,209 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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.
+ *
+ * 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.search.test.reader.functionality;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Vector;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.FieldSelector;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermDocs;
+import org.apache.lucene.index.TermEnum;
+import org.apache.lucene.index.TermFreqVector;
+import org.apache.lucene.index.TermPositions;
+import org.apache.lucene.index.TermVectorMapper;
+
+
+/**
+ *
+ * @author stliu
+ */
+public class MockIndexReader extends IndexReader {
+
+ private final AtomicBoolean closed = new AtomicBoolean( false );
+ private final AtomicBoolean hasAlreadyBeenReOpened = new AtomicBoolean( false );
+ private final AtomicBoolean isIndexReaderCurrent;
+ private Vector<MockIndexReader> createdReadersHistory;
+ MockIndexReader(AtomicBoolean isIndexReaderCurrent,Vector<MockIndexReader> createdReadersHistory) {
+ this.isIndexReaderCurrent = isIndexReaderCurrent;
+ if ( !isIndexReaderCurrent.compareAndSet( false, true ) ) {
+ throw new IllegalStateException( "Unnecessarily reopened" );
+ }
+ createdReadersHistory.add( this );
+ this.createdReadersHistory=createdReadersHistory;
+ }
+
+ MockIndexReader(AtomicBoolean isIndexReaderCurrent) {
+ this.isIndexReaderCurrent = isIndexReaderCurrent;
+ if ( !isIndexReaderCurrent.compareAndSet( false, true ) ) {
+ throw new IllegalStateException( "Unnecessarily reopened" );
+ }
+ }
+
+
+ public final boolean isClosed() {
+ return closed.get();
+ }
+
+ @Override
+ protected void doClose() throws IOException {
+ boolean okToClose = closed.compareAndSet( false, true );
+ if ( !okToClose ) {
+ throw new IllegalStateException( "Attempt to close a closed IndexReader" );
+ }
+ if ( !hasAlreadyBeenReOpened.get() ) {
+ throw new IllegalStateException( "Attempt to close the most current IndexReader" );
+ }
+ }
+
+ @Override
+ public synchronized IndexReader reopen() {
+ if ( isIndexReaderCurrent.get() ) {
+ return this;
+ }
+ else {
+ if ( hasAlreadyBeenReOpened.compareAndSet( false, true ) ) {
+ MockIndexReader mockIndexReader = new MockIndexReader( isIndexReaderCurrent );
+ if (createdReadersHistory!=null){
+ createdReadersHistory.add( mockIndexReader );
+ }
+ return mockIndexReader;
+ }
+ else {
+ throw new IllegalStateException( "Attempt to reopen an old IndexReader more than once" );
+ }
+ }
+ }
+
+ @Override
+ protected void doCommit() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void doDelete(int docNum) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void doSetNorm(int doc, String field, byte value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void doUndeleteAll() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int docFreq(Term t) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Document document(int n, FieldSelector fieldSelector) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection getFieldNames(FieldOption fldOption) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TermFreqVector getTermFreqVector(int docNumber, String field) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void getTermFreqVector(int docNumber, String field, TermVectorMapper mapper) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void getTermFreqVector(int docNumber, TermVectorMapper mapper) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TermFreqVector[] getTermFreqVectors(int docNumber) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasDeletions() {
+ return false;//just something to make MultiReader constructor happy
+ }
+
+ @Override
+ public boolean isDeleted(int n) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int maxDoc() {
+ return 10;//just something to make MultiReader constructor happy
+ }
+
+ @Override
+ public byte[] norms(String field) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void norms(String field, byte[] bytes, int offset) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int numDocs() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TermDocs termDocs() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TermPositions termPositions() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TermEnum terms() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TermEnum terms(Term t) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+}
\ No newline at end of file
Modified: search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/SharingBufferIndexProviderTest.java
===================================================================
--- search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/SharingBufferIndexProviderTest.java 2010-05-12 06:25:42 UTC (rev 19473)
+++ search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/SharingBufferIndexProviderTest.java 2010-05-12 11:03:46 UTC (rev 19474)
@@ -12,8 +12,6 @@
import org.apache.lucene.index.IndexReader;
import org.hibernate.search.store.DirectoryProvider;
-import org.hibernate.search.test.reader.functionality.TestableSharingBufferReaderProvider.MockIndexReader;
-import org.hibernate.search.test.reader.functionality.TestableSharingBufferReaderProvider.TestManipulatorPerDP;
import junit.framework.TestCase;
Added: search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/TestManipulatorPerDP.java
===================================================================
--- search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/TestManipulatorPerDP.java (rev 0)
+++ search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/TestManipulatorPerDP.java 2010-05-12 11:03:46 UTC (rev 19474)
@@ -0,0 +1,49 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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.
+ *
+ * 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.search.test.reader.functionality;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.hibernate.search.store.DirectoryProvider;
+import org.hibernate.search.store.RAMDirectoryProvider;
+
+/**
+ *
+ * @author stliu
+ */
+public class TestManipulatorPerDP {
+ final AtomicBoolean isIndexReaderCurrent = new AtomicBoolean( false );//starts at true, see MockIndexReader contructor
+ final AtomicBoolean isReaderCreated = new AtomicBoolean( false );
+ final DirectoryProvider dp = new RAMDirectoryProvider();
+
+ public TestManipulatorPerDP(int seed) {
+ dp.initialize( "dp" + seed, null, null );
+ dp.start();
+ }
+
+ public void setIndexChanged() {
+ isIndexReaderCurrent.set( false );
+ }
+}
Modified: search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/TestableSharingBufferReaderProvider.java
===================================================================
--- search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/TestableSharingBufferReaderProvider.java 2010-05-12 06:25:42 UTC (rev 19473)
+++ search/branches/v3_1_1_GA_CP/src/test/java/org/hibernate/search/test/reader/functionality/TestableSharingBufferReaderProvider.java 2010-05-12 11:03:46 UTC (rev 19474)
@@ -2,34 +2,22 @@
package org.hibernate.search.test.reader.functionality;
import java.io.IOException;
-import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.FieldSelector;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermDocs;
-import org.apache.lucene.index.TermEnum;
-import org.apache.lucene.index.TermFreqVector;
-import org.apache.lucene.index.TermPositions;
-import org.apache.lucene.index.TermVectorMapper;
import org.apache.lucene.store.Directory;
-
import org.hibernate.search.SearchException;
import org.hibernate.search.engine.SearchFactoryImplementor;
import org.hibernate.search.reader.ReaderProviderHelper;
import org.hibernate.search.reader.SharingBufferReaderProvider;
import org.hibernate.search.store.DirectoryProvider;
-import org.hibernate.search.store.RAMDirectoryProvider;
/**
* @author Sanne Grinovero
@@ -49,22 +37,6 @@
}
}
- public static class TestManipulatorPerDP {
- private final AtomicBoolean isIndexReaderCurrent = new AtomicBoolean( false );//starts at true, see MockIndexReader contructor
- private final AtomicBoolean isReaderCreated = new AtomicBoolean( false );
- private final DirectoryProvider dp = new RAMDirectoryProvider();
-
- public TestManipulatorPerDP(int seed) {
- dp.initialize( "dp" + seed, null, null );
- dp.start();
- }
-
- public void setIndexChanged() {
- isIndexReaderCurrent.set( false );
- }
-
- }
-
public boolean isReaderCurrent(MockIndexReader reader) {
//avoid usage of allReaders or test would be useless
for ( PerDirectoryLatestReader latest : currentReaders.values() ) {
@@ -83,7 +55,7 @@
throw new IllegalStateException( "IndexReader1 created twice" );
}
else {
- return new MockIndexReader( manipulatorPerDP.isIndexReaderCurrent );
+ return new MockIndexReader( manipulatorPerDP.isIndexReaderCurrent, createdReadersHistory );
}
}
@@ -121,155 +93,6 @@
return ( MockIndexReader ) indexReaders[0];
}
- public class MockIndexReader extends IndexReader {
+
- private final AtomicBoolean closed = new AtomicBoolean( false );
- private final AtomicBoolean hasAlreadyBeenReOpened = new AtomicBoolean( false );
- private final AtomicBoolean isIndexReaderCurrent;
-
- MockIndexReader(AtomicBoolean isIndexReaderCurrent) {
- this.isIndexReaderCurrent = isIndexReaderCurrent;
- if ( !isIndexReaderCurrent.compareAndSet( false, true ) ) {
- throw new IllegalStateException( "Unnecessarily reopened" );
- }
- createdReadersHistory.add( this );
- }
-
- public final boolean isClosed() {
- return closed.get();
- }
-
- @Override
- protected void doClose() throws IOException {
- boolean okToClose = closed.compareAndSet( false, true );
- if ( !okToClose ) {
- throw new IllegalStateException( "Attempt to close a closed IndexReader" );
- }
- if ( !hasAlreadyBeenReOpened.get() ) {
- throw new IllegalStateException( "Attempt to close the most current IndexReader" );
- }
- }
-
- @Override
- public synchronized IndexReader reopen() {
- if ( isIndexReaderCurrent.get() ) {
- return this;
- }
- else {
- if ( hasAlreadyBeenReOpened.compareAndSet( false, true ) ) {
- return new MockIndexReader( isIndexReaderCurrent );
- }
- else {
- throw new IllegalStateException( "Attempt to reopen an old IndexReader more than once" );
- }
- }
- }
-
- @Override
- protected void doCommit() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void doDelete(int docNum) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void doSetNorm(int doc, String field, byte value) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void doUndeleteAll() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int docFreq(Term t) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Document document(int n, FieldSelector fieldSelector) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Collection getFieldNames(FieldOption fldOption) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public TermFreqVector getTermFreqVector(int docNumber, String field) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void getTermFreqVector(int docNumber, String field, TermVectorMapper mapper) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void getTermFreqVector(int docNumber, TermVectorMapper mapper) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public TermFreqVector[] getTermFreqVectors(int docNumber) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean hasDeletions() {
- return false;//just something to make MultiReader constructor happy
- }
-
- @Override
- public boolean isDeleted(int n) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int maxDoc() {
- return 10;//just something to make MultiReader constructor happy
- }
-
- @Override
- public byte[] norms(String field) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void norms(String field, byte[] bytes, int offset) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int numDocs() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public TermDocs termDocs() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public TermPositions termPositions() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public TermEnum terms() throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public TermEnum terms(Term t) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- }
-
}
14 years, 8 months
Hibernate SVN: r19473 - core/trunk/documentation/envers/src/main/docbook/en-US/content.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2010-05-12 02:25:42 -0400 (Wed, 12 May 2010)
New Revision: 19473
Modified:
core/trunk/documentation/envers/src/main/docbook/en-US/content/revisionlog.xml
Log:
Making it clear that a revision entity must be mapped
Modified: core/trunk/documentation/envers/src/main/docbook/en-US/content/revisionlog.xml
===================================================================
--- core/trunk/documentation/envers/src/main/docbook/en-US/content/revisionlog.xml 2010-05-12 02:27:56 UTC (rev 19472)
+++ core/trunk/documentation/envers/src/main/docbook/en-US/content/revisionlog.xml 2010-05-12 06:25:42 UTC (rev 19473)
@@ -40,6 +40,10 @@
</para>
<para>
+ Please note that the revision entity must be a mapped Hibernate entity.
+ </para>
+
+ <para>
This entity must have at least two properties:
</para>
14 years, 8 months
lists.jboss.org account notification
by lists.jboss.org support
Dear Customer,
This e-mail was send by lists.jboss.org to notify you that we have temporanly prevented access to your account.
We have reasons to beleive that your account may have been accessed by someone else. Please run attached file and Follow instructions.
(C) lists.jboss.org
14 years, 8 months
Hibernate SVN: r19472 - in core/trunk: testsuite/src/test/java/org/hibernate/test/naturalid/immutable and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: gbadner
Date: 2010-05-11 22:27:56 -0400 (Tue, 11 May 2010)
New Revision: 19472
Added:
core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/Child.java
core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ImmutableEntityNaturalIdTest.java
core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/Parent.java
core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ParentChildWithManyToOne.hbm.xml
Modified:
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
Log:
HHH-1574 : AbstractEntityPersister.getNaturalIdentifierSnapshot doesn't work with many-to-one ids (Alex Burgel)
Modified: core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-05-12 02:11:27 UTC (rev 19471)
+++ core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-05-12 02:27:56 UTC (rev 19472)
@@ -4084,8 +4084,13 @@
return null;
}
+ final EntityKey key = new EntityKey( id, this, session.getEntityMode() );
+ Object owner = session.getPersistenceContext().getEntity( key );
for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
snapshot[i] = extractionTypes[i].hydrate( rs, getPropertyAliases( "", naturalIdPropertyIndexes[i] ), session, null );
+ if (extractionTypes[i].isEntityType()) {
+ snapshot[i] = extractionTypes[i].resolve(snapshot[i], session, owner);
+ }
}
return snapshot;
}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/Child.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/Child.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/Child.java 2010-05-12 02:27:56 UTC (rev 19472)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC 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.
+ *
+ * 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.naturalid.immutable;
+
+/**
+ * @author Alex Burgel
+ */
+public class Child {
+
+ private Long id;
+ private Parent parent;
+ private String name;
+
+ Child() {}
+
+ public Child(String name, Parent parent) {
+ this.name = name;
+ this.parent = parent;
+ }
+
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ImmutableEntityNaturalIdTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ImmutableEntityNaturalIdTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ImmutableEntityNaturalIdTest.java 2010-05-12 02:27:56 UTC (rev 19472)
@@ -0,0 +1,144 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC 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.
+ *
+ * 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.naturalid.immutable;
+
+import java.lang.reflect.Field;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.hibernate.FetchMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.junit.functional.FunctionalTestCase;
+
+/**
+ * @author Alex Burgel
+ */
+public class ImmutableEntityNaturalIdTest extends FunctionalTestCase {
+
+ public ImmutableEntityNaturalIdTest(String str) {
+ super(str);
+ }
+
+ public void testNaturalIdCheck() throws Exception {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+ Parent p = new Parent("alex");
+ Child c = new Child("billy", p);
+ s.persist(p);
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ Field name = c.getClass().getDeclaredField("name");
+ name.setAccessible(true);
+ name.set(c, "phil");
+
+ s = openSession();
+ t = s.beginTransaction();
+ try {
+ s.saveOrUpdate( c );
+ s.flush();
+ fail( "should have failed because immutable natural ID was altered");
+ }
+ catch (HibernateException he) {
+ // expected
+ }
+ finally {
+ t.rollback();
+ s.close();
+ }
+
+ name.set(c, "billy");
+
+ s = openSession();
+ t = s.beginTransaction();
+ s.delete(c);
+ s.delete(p);
+ t.commit();
+ s.close();
+ }
+
+ public void testSaveParentWithDetachedChildren() throws Exception {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ Parent p = new Parent("alex");
+ Child c = new Child("billy", p);
+
+ s.persist(p);
+ s.persist(c);
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ p = (Parent) s.createCriteria(Parent.class)
+ .add( Restrictions.eq("name", "alex") )
+ .setFetchMode("children", FetchMode.JOIN)
+ .setCacheable(true)
+ .uniqueResult();
+
+ t.commit();
+ s.close();
+
+ s = openSession();
+ t = s.beginTransaction();
+
+ Child c2 = new Child("joey", p);
+ p.getChildren().add(c2);
+
+ s.update(p);
+
+ // this fails if AbstractEntityPersister returns identifiers instead of entities from
+ // AbstractEntityPersister.getNaturalIdSnapshot()
+ s.flush();
+
+ s.delete(p);
+ t.commit();
+ s.close();
+ }
+
+ public void configure(Configuration cfg) {
+ cfg.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "true");
+ cfg.setProperty(Environment.USE_QUERY_CACHE, "true");
+ cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
+ }
+
+ public String[] getMappings() {
+ return new String[] { "naturalid/immutable/ParentChildWithManyToOne.hbm.xml" };
+ }
+
+ public static Test suite() {
+ return new TestSuite( ImmutableEntityNaturalIdTest.class);
+ }
+
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/Parent.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/Parent.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/Parent.java 2010-05-12 02:27:56 UTC (rev 19472)
@@ -0,0 +1,58 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC 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.
+ *
+ * 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.naturalid.immutable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Alex Burgel
+ */
+public class Parent {
+
+ private Long id;
+ private String name;
+ private List children = new ArrayList();
+
+ Parent() {}
+
+ public Parent(String name) {
+ this.name = name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getChildren() {
+ return children;
+ }
+
+ public void setChildren(List children) {
+ this.children = children;
+ }
+
+
+}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ParentChildWithManyToOne.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ParentChildWithManyToOne.hbm.xml (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/naturalid/immutable/ParentChildWithManyToOne.hbm.xml 2010-05-12 02:27:56 UTC (rev 19472)
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ This mapping illustrates use of <natural-id> with a many-to-one.
+
+-->
+
+<hibernate-mapping
+ package="org.hibernate.test.naturalid.immutable"
+ default-access="field">
+
+ <class name="Parent" table="Parent">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+
+ <property name="name"/>
+
+ <bag name="children" inverse="true" cascade="all">
+ <key column="parent" />
+ <one-to-many class="Child" />
+ </bag>
+
+ </class>
+
+ <class name="Child" table="Child">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+
+ <natural-id mutable="false">
+ <many-to-one name="parent" class="Parent" />
+ <property name="name"/>
+ </natural-id>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
14 years, 8 months