Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MappingException: Could not interpret id generator strategy with custom id generator

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.

like image 328
barclay Avatar asked Jan 23 '14 16:01

barclay


People also ask

How would you implement a custom sequence based id generator?

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.

How to create Custom sequence in Hibernate?

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.


1 Answers

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"
like image 189
Mikko Maunu Avatar answered Sep 27 '22 22:09

Mikko Maunu