I need a custom id generator that saves the last used id rather than the next available, so based on this answer https://stackoverflow.com/a/10648572/187423 I created a custom generator extending TableGenerator.
I've determined in debug mode that my custom generator is not getting added to org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.generatorStrategyToClassNameMap, so it doesn't know how to interpret my generator. (It also seems that I should be using a handle rather than a class name, but again - not sure how to get this into the map.)
I'm also using Dropwizard, which complicates things. I'm not sure how or where I need to let DW know about my custom generator, but I've tried adding my class to the HibernateBundle, to the run() method in my DW service, to the injector, etc.
Here's where I use my generator in the class:
public class MexpFeedError {
private int mexpFeedErrorId;
@Id
@GeneratedValue(strategy=GenerationType.TABLE, generator = "MEXPFEEDERROR_GEN")
@GenericGenerator(name = "MEXPFEEDERROR_GEN", strategy = "com.pronto.util.ProntoPersistJustUsedGenerator",
parameters = {
@org.hibernate.annotations.Parameter(name = "table_name", value = "sequence"),
@org.hibernate.annotations.Parameter(name = "segment_value", value = "seq_mexpfeederrorid"),
@org.hibernate.annotations.Parameter(name = "value_column_name", value = "sequence_value"),
@org.hibernate.annotations.Parameter(name = "segment_column_name", value = "sequence_name") })
public int getMexpFeedErrorId() {
return mexpFeedErrorId;
}
...
}
Here's my custom generator:
package com.pronto.util.hibernate;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.enhanced.TableGenerator;
import java.io.Serializable;
@SuppressWarnings("UnusedDeclaration")
public class ProntoPersistJustUsedGenerator extends TableGenerator {
@Override
public synchronized Serializable generate(SessionImplementor session, Object obj) {
return (Long) super.generate(session, obj) + 1;
}
}
Here's the stack trace:
Exception in thread "main" org.hibernate.MappingException: Could not instantiate id generator [entity-name=com.pronto.mpds.entity.MexpFeedError]
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:123)
at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:195)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:314)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1769)
at com.yammer.dropwizard.hibernate.SessionFactoryFactory.buildSessionFactory(SessionFactoryFactory.java:77)
at com.yammer.dropwizard.hibernate.SessionFactoryFactory.build(SessionFactoryFactory.java:35)
at com.yammer.dropwizard.hibernate.HibernateBundle.run(HibernateBundle.java:38)
at com.yammer.dropwizard.hibernate.HibernateBundle.run(HibernateBundle.java:13)
at com.yammer.dropwizard.config.Bootstrap.runWithBundles(Bootstrap.java:77)
at com.yammer.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:37)
at com.yammer.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:58)
at com.yammer.dropwizard.cli.Cli.run(Cli.java:53)
at com.yammer.dropwizard.Service.run(Service.java:61)
at com.pronto.mpds.service.DropwizardMPDSService.main(DropwizardMPDSService.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.hibernate.MappingException: Could not interpret id generator strategy [com.pronto.util.ProntoSequenceStyleGenerator]
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.getIdentifierGeneratorClass(DefaultIdentifierGeneratorFactory.java:140)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:114)
... 18 more
Hope there's a wizard out there with some useful ideas for me. Thanks.
If you want to use a custom generator, you need to define the generator in a @GenericGenerator annotation and provide the fully-qualified classname as the strategy. You can also configure a set of parameters that will be provided to the configure method when Hibernate instantiates the generator.
In order to customize the sequence name, we can use the @GenericGenerator annotation with SequenceStyleGenerator strategy: @Entity public class User { @Id @GeneratedValue(generator = "sequence-generator") @GenericGenerator( name = "sequence-generator", strategy = "org. hibernate.
ProntoPersistJustUsedGenerator is located to com.pronto.util.hibernate
package, butcom.pronto.util
package is used in GenericGenerator
annotation.
Problem goes away when using full package name as a value of strategy attribute:
strategy = "com.pronto.util.hibernate.ProntoPersistJustUsedGenerator"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With