Search code examples
javahibernatejpahibernate-annotations

Are SequenceGenerators names globally unique in hibernate 5?


I am upgrading from Hibernate 4.3 to 5.2.13. I have a pattern where many entities inherit properties from an abstract class which is itself annotated. For example:

Entity A:

@AttributeOverride(name = "id", column = @Column(name = "table_a_id"))
@Entity
@SequenceGenerator(name = "IdSequenceGenerator", sequenceName = "table_a_seq")
@Table(name = "table_a")
public class EntityA extends Identity {

}

Entity B:

@AttributeOverride(name = "id", column = @Column(name = "table_b_id"))
@Entity
@SequenceGenerator(name = "IdSequenceGenerator", sequenceName = "table_b_seq")
@Table(name = "table_b")
public class EntityB extends Identity {

}

Parent class:

@MappedSuperclass
public abstract class Identity {

    private Long id;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "IdSequenceGenerator")
    public Long getId()
    {
        return id;
    }
}

This worked okay under Hibernate 4, but I'm getting the bellow exception. By this, I am assuming that the sequence generator name was not required to be globally unique but now it is. Is that the case? Is there a way that I can solve this with configuration rather than changing many (many) entities?

I'm getting this error:

Caused by: java.lang.IllegalArgumentException: Duplicate generator name IdSequenceGenerator
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.addIdentifierGenerator(InFlightMetadataCollectorImpl.java:448)
    at org.hibernate.cfg.AnnotationBinder.lambda$buildGenerators$0(AnnotationBinder.java:3369)
    at java.util.HashMap.forEach(HashMap.java:1288)
    at org.hibernate.cfg.AnnotationBinder.buildGenerators(AnnotationBinder.java:3368)
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:728)
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:249)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:222)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:265)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:691)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:439)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    ... 54 more

Solution

  • Thanks to @maheshkumar. Copying his comment.

    A sequence generator may be specified on the entity class or on the primary key field or property. The scope of the generator name is global to the persistence unit (across all generator types).