Generate Custom Identifier in Hibernate

hibernate_image

Sometimes, we want to generate our table's primary key with more custom information. Custom Identifiers contains more information for us which helps us to distinguish and identify the records. It adds more meaning to an identifier.

For example, an event Identifier like - 20220219000045 has two parts, the first part is the date and the second part is the sequence generated number. 

YYYYMMDD + 6 digit number generated by the sequence
This type of identifier tells us that this event is created on the date: 21/02/2022. Similarly, we might have different requirements to generate custom Identifiers. 

In the post, I will show how can we generate simple sequence based custom identifier in Hibernate.
The custom Identifier can be generated in Hibernate by defining our own Identifier generator which implements the Hibernate IdentifierGenerator interface. However, if you have a database that supports sequences like Oracle RDBMS then you can use SequenceStyleGenerator class in hibernate. In this post, I will use custom SequenceStyleGenerator

Let's first create an entity called Event and add a Sequence Id generator. We need to specify the Identifier generator as a strategy that will be used by Hibernate to generate Identifier for the column. You can provide parameters for sequence like optimization strategy (OPT_PARAM), database sequence name (SEQUENCE_PARAM), etc.

Event.java

@Entity
@Table( name = "EVENT" )
public class Event {
 
    @Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "eventIdGenerator")
	@GenericGenerator(
		name = "eventIdGenerator",
		strategy = "com.demo.EventIdGenerator", 
		parameters = {
			@Parameter( name = SequenceStyleGenerator.OPT_PARAM, value = "hilo"),
			@Parameter( name = SequenceStyleGenerator.SEQUENCE_PARAM, value = "EVENT_ID_SEQ"),
			@Parameter( name = SequenceStyleGenerator.INITIAL_PARAM, value = "1"),	
			@Parameter( name = SequenceStyleGenerator.INCREMENT_PARAM, value = "20")
		})
    @Column(name = "EVENT_ID")
    private Long eventId;
 
    @Column
    private String eventType;
 
    @Column
    private LocalDate eventDate;
 
    //Getters & Setters
	...
   }
Now extends the hibernate SequenceStyleGenerator class to generate your own style of identifiers. The below class will generate 18 digits Long identifier. First, eight-digit will be generated from the current date, and the remaining 10 digits will be generated by the sequence with a padding of 0. 
Sample Identifier generated  - 202202190000000078

EventIdGenerator.java

package com.demo;

public class EventIdGenerator extends SequenceStyleGenerator {
     
    public static final String DATEFORMAT_PARAM = "dateFormat";
    public static final String DATEFORMAT_DEFAULT = "%tY%tm%td";
     
    public static final String NUM_FORMAT_PARAM = "numberFormat";
    public static final String NUM_FORMAT_DEFAULT = "%010d";
     
       
    private String format;
    
    /**
     * Generates 18 digit long number, first 8 digits are taken 
     * from current date as YYYYMMDD and remaining from sequence with 
     * padding value of 0. 
     *
     */
     
    @Override
    public Serializable generate(SessionImplementor session,
            Object object) throws HibernateException {
		Date currentDate = new Date();	
        return Long.parseLong(String.format(format, currentDate, currentDate, currentDate, super.generate(session, object)));
    }
 
    @Override
    public void configure(Type type, Properties params,
            ServiceRegistry serviceRegistry) throws MappingException {
        super.configure(LongType.INSTANCE, params, serviceRegistry);
 
        String dateFormat = ConfigurationHelper.getString(DATEFORMAT_PARAM, params, DATEFORMAT_DEFAULT).replace("%", "%"); 
        String numberFormat = ConfigurationHelper.getString(NUM_FORMAT_PARAM, params, NUM_FORMAT_DEFAULT).replace("%", "%"); 
        this.format = dateFormat+numberFormat; 
    } 
}
Please suggest in comment section about your approach to generate custom identifiers.

Comments

Popular posts from this blog

Creating simple Maven multi module project in Java

Tricky Java Questions

How to update existing CCDT file (AMQCLCHL.TAB) for successful MQueue connection