如何在JPA中动态创建序列生成器

huangapple go评论72阅读模式
英文:

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

我想通过动态地将序列名称 order_sequence 传递给这个类来重用 Counter,应该如何实现?

英文:

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;

}

答案1

得分: 1

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")
英文:

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(&quot;Entity name must not be null&quot;);
        }

        Class&lt;?&gt; entityClass = serviceRegistry.requireService(ClassLoaderService.class)
                .classForName(entityName);

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

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

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

}

MappedSuperClass:

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

Child classes:

@Entity
@EntityAwareGeneratorParams(sequence=&quot;another sequence&quot;)

huangapple
  • 本文由 发表于 2023年4月13日 17:36:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003921.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定