# How to write a custom sequence-based String Id generator with JPA and Hibernate

**URL:** <https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306>\
**Category:** Hibernate ORM\
**Created:** [February 16, 2019, 11:42am UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306 "2019-02-16T11:42:50Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Harish](https://avatars.discourse-cdn.com/v4/letter/h/47e85d/32.png) [@Harish](https://discourse.hibernate.org/u/Harish)\
**Post date:** [February 16, 2019, 11:42am UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/1 "2019-02-16T11:42:50Z")

</div>

i am new to hibernate. i was trying to create custom id of type string using hibernate and mysql. can someone help me with how to override generator class?

here is my hbm file

```
<class name="com.usermanagement.model.Employee" table="EMPLOYEE">
    <id name="id" column= "ID">
	<generator class="com.customid.EmployeeIdGenerator"/>
    </generator>
    </id>
    <property name="name" type="java.lang.String">
        <column name="NAME" />
    </property>
</class>

```

The id i am trying to generate is like str001, str002, str003…

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [February 16, 2019, 12:09pm UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/2 "2019-02-16T12:09:33Z")

</div>

You can write a String identifier generator like this one:

```auto
public class StringSequenceIdentifier implements 
        IdentifierGenerator, Configurable {

    public static final String SEQUENCE_PREFIX = "sequence_prefix";

    private String sequencePrefix;

    private String sequenceCallSyntax;

    @Override
    public void configure(
            Type type,
            Properties params,
            ServiceRegistry serviceRegistry)
        throws MappingException {

        final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(
                JdbcEnvironment.class
        );

        final Dialect dialect = jdbcEnvironment.getDialect();

        final ConfigurationService configurationService = serviceRegistry.getService(
                ConfigurationService.class
        );

        String globalEntityIdentifierPrefix = configurationService.getSetting(
            "entity.identifier.prefix",
            String.class,
            "SEQ_"
        );

        sequencePrefix = ConfigurationHelper.getString(
            SEQUENCE_PREFIX,
            params,
            globalEntityIdentifierPrefix
        );

        final String sequencePerEntitySuffix = ConfigurationHelper.getString(
            SequenceStyleGenerator.CONFIG_SEQUENCE_PER_ENTITY_SUFFIX,
            params,
            SequenceStyleGenerator.DEF_SEQUENCE_SUFFIX
        );

        boolean preferSequencePerEntity = ConfigurationHelper.getBoolean(
            SequenceStyleGenerator.CONFIG_PREFER_SEQUENCE_PER_ENTITY,
            params,
            false
        );

        final String defaultSequenceName = preferSequencePerEntity
                ? params.getProperty(JPA_ENTITY_NAME) + sequencePerEntitySuffix
                : SequenceStyleGenerator.DEF_SEQUENCE_NAME;

        sequenceCallSyntax = dialect.getSequenceNextValString(
            ConfigurationHelper.getString(
                SequenceStyleGenerator.SEQUENCE_PARAM,
                params,
                defaultSequenceName
            )
        );
    }

    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object obj) {
        if (obj instanceof Identifiable) {
            Identifiable identifiable = (Identifiable) obj;
            Serializable id = identifiable.getId();

            if (id != null) {
                return id;
            }
        }

        long seqValue = ((Number)
                Session.class.cast(session)
                .createNativeQuery(sequenceCallSyntax)
                .uniqueResult()
        ).longValue();

        return sequencePrefix + String.format("%011d%s", 0 ,seqValue);
    }
}

```

And map it like this:

```auto
@Id
@GenericGenerator(
	name = "assigned-sequence",
	strategy = "com.vladmihalcea.book.hpjp.hibernate.identifier.StringSequenceIdentifier",
	parameters = {
		@org.hibernate.annotations.Parameter(
			name = "sequence_name", value = "hibernate_sequence"),
		@org.hibernate.annotations.Parameter(
			name = "sequence_prefix", value = "CTC_"),
	}
)
@GeneratedValue(
	generator = "assigned-sequence",
	strategy = GenerationType.SEQUENCE)
private String id;

```

Check out [this article](https://vladmihalcea.com/how-to-implement-a-custom-string-based-sequence-identifier-generator-with-hibernate/) for more details.

---

<div class="post-metadata">

**Author:** ![Harish](https://avatars.discourse-cdn.com/v4/letter/h/47e85d/32.png) [@Harish](https://discourse.hibernate.org/u/Harish)\
**Post date:** [February 16, 2019, 12:22pm UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/3 "2019-02-16T12:22:25Z")

</div>

Thanks but is it possible to do it with just xml instead of using annotations for mapping?

---

<div class="post-metadata">

**Author:** ![Harish](https://avatars.discourse-cdn.com/v4/letter/h/47e85d/32.png) [@Harish](https://discourse.hibernate.org/u/Harish)\
**Post date:** [February 16, 2019, 12:32pm UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/4 "2019-02-16T12:32:16Z")

</div>

why is it asking me to implement unimplemented methods in class name

it implements the following sets of code  
@Override  
public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {  
// TODO Auto-generated method stub  
return null;  
}  
}

also it asks me to remove @Override from generate method

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [February 16, 2019, 12:43pm UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/5 "2019-02-16T12:43:31Z")

</div>

Yes, you can use XML too, but why would you use a deprecated mapping model?

It seems you are using an old Hibernate version. Upgrade to 5.2 and it will work. Or adapt it to the old method signature. It’s very easy. You’ll figure it out.

---

<div class="post-metadata">

**Author:** ![Harish](https://avatars.discourse-cdn.com/v4/letter/h/47e85d/32.png) [@Harish](https://discourse.hibernate.org/u/Harish)\
**Post date:** [February 16, 2019, 1:19pm UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/6 "2019-02-16T13:19:00Z")

</div>

i’m using the latest version of hibernate and JPA

These are my gradle dependencies  
implementation ‘org.springframework.boot:spring-boot-starter-web’  
implementation ‘mysql:mysql-connector-java:8.0.15’  
implementation ‘org.hibernate:hibernate-core:5.4.1.Final’  
implementation ‘org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final’

i m confused.

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [February 16, 2019, 2:11pm UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/7 "2019-02-16T14:11:54Z")

</div>

Check out my [`StringSequenceIdentifierTest`](https://github.com/vladmihalcea/high-performance-java-persistence/blob/951db3fb0f6e9e699d4023044aa6baaeaec54696/core/src/test/java/com/vladmihalcea/book/hpjp/hibernate/identifier/StringSequenceIdentifierTest.java) in my `high-performance-java-persistence` GitHub repository.

Just run the test and you’ll see that it works like a charm.

---

<div class="post-metadata">

**Author:** ![Harish](https://avatars.discourse-cdn.com/v4/letter/h/47e85d/32.png) [@Harish](https://discourse.hibernate.org/u/Harish)\
**Post date:** [February 19, 2019, 2:23am UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/8 "2019-02-19T02:23:32Z")

</div>

Is that custom string id possible with MySQL db?

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [February 19, 2019, 4:07am UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/9 "2019-02-19T04:07:21Z")

</div>

MySQL does not support sequences, so you could not do that for the PK. Only if thevPK is identity and you use that value to build a secondary column with the String prefix amd the ID value combined.

---

<div class="post-metadata">

**Author:** ![NAVEEN\_NAVEEN](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/naveen_naveen/32/2355_2.png) [@NAVEEN\_NAVEEN](https://discourse.hibernate.org/u/NAVEEN_NAVEEN)\
**Post date:** [March 31, 2023, 4:50pm UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/10 "2023-03-31T16:50:35Z")

</div>

Hi @vlad  
I have a issue in generating custom sequence using SequenceStyleGenerator  
Can you look into it

> **[How to Implement a Custom, Sequence-Based IdGenerator](https://thorben-janssen.com/custom-sequence-based-idgenerator/)**
>
> A lot of applications use IDs that are based on a sequence but use an additional prefix. You can easily support these IDs with a custom id generator.

The issue is due to LongType is deprecated in hibarnate 6

---

<div class="post-metadata">

**Author:** ![Nick\_Nguyen](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/nick_nguyen/32/2500_2.png) [@Nick\_Nguyen](https://discourse.hibernate.org/u/Nick_Nguyen)\
**Post date:** [June 19, 2023, 7:33am UTC](https://discourse.hibernate.org/t/how-to-write-a-custom-sequence-based-string-id-generator-with-jpa-and-hibernate/2306/11 "2023-06-19T07:33:29Z")

</div>

Better late than never!  
Regarding the LongType issue, you can switch to:  
`super.configure(new TypeConfiguration().getBasicTypeRegistry().getRegisteredType(Long.class), params, serviceRegistry);`

@vlad your post helped the community so much on SequenceStyleGenerator usage, I’m wondering if you have a plan to have another post for using SequenceStyleGenerator in Hibernate 6, as well as new supports for strong type. I believe it will be super helpful. (Sorry if this is unrelated)
