Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate cfg.xml configuration for sequence generator

Fellow developers, I'm finding it hard to get the sequence generation configured.

I inherited a persistent class with the following id field definition:

@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;

All of my classes inherit from this class.

The main thing I want: I need to override the strategy of id generation to use HiLo. It has to be in the cfg.xml since it's the only place that I have control over.

This thing looked promising:

<property name="hibernate.id.new_generator_mappings">true</property>

However I couldn't choose the optimize, or the increment size (I want to go HiLo)

<property name="hibernate.id.increment_size">50</property>
<property name="hibernate.id.optimizer">hilo</property>

didn't work, nor

<property name="increment_size">50</property>
<property name="optimizer">hilo</property>

nor

<property name="optimizer">org.hibernate.id.enhanced.HiLoOptimizer</property>

The NoopOptimizer is always chosen.

Any tip will help. Thanks a lot in advance.

like image 930
Eyad Ebrahim Avatar asked Dec 20 '25 16:12

Eyad Ebrahim


1 Answers

Let's do some investigation (looking at the Hibernate sources):

The AnnotationBinder defines how AUTO is mapped:

switch ( generatorEnum ) {
  // ...
  case AUTO:
    return useNewGeneratorMappings ? 
      org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName() : "native";
  // ...

If you don't use the NewGeneratorMappings you're stuck with the native implementation. Hibernate will resolve that depending on the database (see this answer to see what that will be for your specific database).

But since you used the NewGeneratorMappings we have to look at the SequenceStyleGenerator:

protected String determineOptimizationStrategy(Properties params, int incrementSize) {

  // ... some stuff to calculate defaultOptimizerStrategy

  // OPT_PARAM = "optimizer"
  return ConfigurationHelper.getString( OPT_PARAM, params, defaultOptimizerStrategy);
}

Assuming the right Properties are passed and you have an "optimizer" property in them then your value should be returned. This value is used to call OptimizerFactory.buildOptimizer (as the first parameter):

 public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize) {
   final Class<? extends Optimizer> optimizerClass;

   final StandardOptimizerDescriptor standardDescriptor = 
     StandardOptimizerDescriptor.fromExternalName( type ); // HILO("hilo", HiLoOptimizer.class),
   if ( standardDescriptor != null ) {
     optimizerClass = standardDescriptor.getOptimizerClass();
   }
   else {
     try {
       optimizerClass = ReflectHelper.classForName( type );
     }
   catch( Throwable ignore ) {
     LOG.unableToLocateCustomOptimizerClass( type );
     return buildFallbackOptimizer( returnClass, incrementSize );
   }
 }

 try {
   final Constructor ctor = optimizerClass.getConstructor( CTOR_SIG );
   return (Optimizer) ctor.newInstance( returnClass, incrementSize );
 }
 catch( Throwable ignore ) {
   LOG.unableToInstantiateOptimizer( type );
 }

  return buildFallbackOptimizer( returnClass, incrementSize );
}

private static Optimizer buildFallbackOptimizer(Class returnClass, int incrementSize) {
  return new NoopOptimizer( returnClass, incrementSize );
}

So either it finds your value "hilo" (or your "HiLoOptimizer"), instantiates it and returns it or it will log some error message. If you find no error message in your logs I would check whether the properties in the cfg.xml are actually really used. Try to access them with getProperties() on your org.hibernate.internal.SessionFactoryImpl instance.

like image 67
xwoker Avatar answered Dec 23 '25 07:12

xwoker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!