Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically create sequence generators in JPA

I want to reuse Counter by passing the sequence name order_sequence dynamically to this class, how can this be achieved

public class Counter  {
    
    @Id
    @GeneratedValue(generator = "sequence-generator")
    @GenericGenerator(name = "sequence-generator", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = {
            @Parameter(name = "sequence_name", value = "order_sequence"),
            @Parameter(name = "initial_value", value = "1"), @Parameter(name = "increment_size", value = "1") })
    private Long counter;

}
like image 583
user352290 Avatar asked Dec 05 '25 18:12

user352290


1 Answers

The main idea could be override org.hibernate.id.enhanced.SequenceStyleGenerator in the following way:

@Target(TYPE)
@Retention(RUNTIME)
@Inherited
public @interface EntityAwareGeneratorParams {

    String sequence();

}
public class EntityAwareGenerator extends SequenceStyleGenerator {

    public static final String NAME = EntityAwareGenerator.class.getName();

    @Override
    public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
        String entityName = params.getProperty(ENTITY_NAME);
        if (entityName == null) {
            throw new IllegalStateException("Entity name must not be null");
        }

        Class<?> entityClass = serviceRegistry.requireService(ClassLoaderService.class)
                .classForName(entityName);

        EntityAwareGeneratorParams generatorParams = entityClass.getAnnotation(EntityAwareGeneratorParams.class);
        if (generatorParams == null) {
            throw new IllegalStateException(String.format(
                    "Annotation @%s is not present for class %s",
                    EntityAwareGeneratorParams.class.getName(),
                    entityClass.getName()
            ));
        }

        params.setProperty(SEQUENCE_PARAM, generatorParams.sequence());

        super.configure(type, params, serviceRegistry);
    }

}

MappedSuperClass:

@Id
@GeneratedValue(generator = "entity-aware-generator", strategy = GenerationType.SEQUENCE)
@GenericGenerator(name = "entity-aware-generator", strategy = EntityAwareGenerator.NAME, ...)
private Long id;

Child classes:

@Entity
@EntityAwareGeneratorParams(sequence="another sequence")
like image 96
Andrey B. Panfilov Avatar answered Dec 08 '25 07:12

Andrey B. Panfilov



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!