Generate sequential java number with Hibernate

Asked

Viewed 1,032 times

6

Is there any way using Hibernate generate a custom number to be the identification number of a particular record?

I have a system that stores care performed to a patient, every time a new care is created is generated by auto increment of the bank the numbering of this record, but I would like to be generated a more composite number like: (Year - Month - Day - Hour - Minute - Self-improvement id)

My id is mapped like this:

@Id
@GeneratedValue
public Long getRegistro() {
    return registro;
}

Would you like to customize this Generatedvalue, is that possible? I looked into it but I got a little confused on how to do, I’m still beginner with Hibernate.

  • Fábio, welcome to [pt.so]! You could simply have a timestamp field. Is there any reason to want such a complicated composite key? It would only make your program and its use more complex than necessary.

  • 1

    @utluiz thank you very much for your attention. Really analyzing well there is no specific reason to create such a complicated and complex identification code. Even because I’ve been reading and researching and putting the identification code with this complication can bring me problems in the future. I decided to leave as it is, I just made a modification so that the stored number was always with 4 houses, instead of 1 it will be as 0001.

  • Cool, @Fabio. If you want, you can post your solution as an answer to your own question. This will help other people in the future.

  • @utluiz thank you very much for your attention. Really analyzing well there is no specific reason to create such a complicated and complex identification code. Even because I’ve been reading and researching and putting the identification code with this complication can bring me problems in the future. I decided to leave as it is, I just made a modification so that the stored number was always with 4 houses, instead of 1 it will be as 0001.

2 answers

1

Yes there is, just create a generator and specify it in the column that is the ID, in the example below I will create the id based on the model and year of the car.

The Entity:

@Entity
public class Carro {

    @Id
    @GenericGenerator(name = "geradorId", strategy = "com.example.GeradorIDCarro")
    @GeneratedValue(generator = "geradorId")
    private String id;

    @Column
    private String modelo;

    @Column
    private int ano;

    // getters and setters
}

And the class that generates the custom ID:

package com.example;

import java.io.Serializable;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.IdentifierGenerator;

public class GeradorIDCarro implements IdentifierGenerator {
    @Override
    public Serializable generate(SessionImplementor session, Object object)
            throws HibernateException
    {
        final Carro entity = (Carro) object;
        return entity.getModelo() + '-' + entity.getAno();
    }
}

Reference.

  • Important note: From Hibernate 5.2, the first parameter of the method generate became the type SharedSessionContractImplementor.

0


I know that the question is very old but recently I found a solution that has now solved my difficulty, I will leave here because, it may be that one day needs.

How to declare the field with the generated numbering

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "registro_seq")
    @GenericGenerator(name = "registro_seq", strategy = "br.com.pegasus.util.RegistroPrefixedSequenceIdGenerator", parameters = {
            @Parameter(name = RegistroPrefixedSequenceIdGenerator.INCREMENT_PARAM, value = "1") })
    private String registro;

Generator Formatter Class (Registroprefixedsequenceidgenerator)

import java.io.Serializable;
import java.time.LocalDate;
import java.util.Properties;

import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.LongType;
import org.hibernate.type.Type;

public class RegistroPrefixedSequenceIdGenerator extends SequenceStyleGenerator {

    public static final String DATE_FORMAT_PARAMETER = "dateFormat";
    public static final String DATE_FORMAT_DEFAULT = "%tY";

    public static final String NUMBER_FORMAT_PARAMETER = "numberFormat";
    public static final String NUMBER_FORMAT_DEFAULT = "%05d";

    public static final String DATE_NUMBER_SEPARATOR_PARAMETER = "dateNumberSeparator";
    public static final String DATE_NUMBER_SEPARATOR_DEFAULT = "0";

    private String format;

    @Override
    public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
        return String.format(format, LocalDate.now(), super.generate(session, object));
    }

    @Override
    public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
        // TODO Auto-generated method stub
        super.configure(LongType.INSTANCE, params, serviceRegistry);

        String dateFormat = ConfigurationHelper.getString(DATE_FORMAT_PARAMETER, params, DATE_FORMAT_DEFAULT)
                .replace("%", "%1$");
        String numberFormat = ConfigurationHelper.getString(NUMBER_FORMAT_PARAMETER, params, NUMBER_FORMAT_DEFAULT)
                .replace("%", "%2$");
        ;
        String dateNumberSeparator = ConfigurationHelper.getString(DATE_NUMBER_SEPARATOR_PARAMETER, params,
                DATE_NUMBER_SEPARATOR_DEFAULT);

        this.format = dateFormat + dateNumberSeparator + numberFormat;
    }

}

It is necessary in the database to have this table, which will control the generation of the next number to be generated.

Table in the bank

CREATE TABLE hibernate_sequence (
    next_val BIGINT(20)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO hibernate_sequence VALUE(1);

That’s it, with this modification can generate a custom number, for the ID

The solution was not developed by me, but after a long time trying to find something that solved my previous doubt of years ago, I leave the link of the source, all credits for the solution belong to the author.

Source: https://thoughts-on-java.org/custom-sequence-based-idgenerator/

Browser other questions tagged

You are not signed in. Login or sign up in order to post.