Custom Hibernate Sequence Generator for Id field

I have a table with a primary key in the format M001, M002 etc (lets not think about what happens after M999 for now). I’m using Hibernate Annotations, and I found a great way of generating the Primary Key value for new Records:

First I created a database sequence to use. Then I implemented org.hibernate.id.IdentifierGenerator;

public class StockCodeGenerator implements IdentifierGenerator {

    private static Logger log = Logger.getLogger(StockCodeGenerator.class);

    public Serializable generate(SessionImplementor session, Object object)
            throws HibernateException {

        String prefix = "M";
        Connection connection = session.connection();
        try {

            PreparedStatement ps = connection
                    .prepareStatement("SELECT nextval ('seq_stock_code') as nextval");

            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                int id = rs.getInt("nextval");
                String code = prefix + StringUtils.leftPad("" + id,3, '0');
                log.debug("Generated Stock Code: " + code);
                return code;
            }

        } catch (SQLException e) {
            log.error(e);
            throw new HibernateException(
                    "Unable to generate Stock Code Sequence");
        }
        return null;
    }
}

Then, in my entity class, I simply annotate the id field like this:

@Id
@GenericGenerator(name="seq_id", strategy="my.package.StockCodeGenerator")
@GeneratedValue(generator="seq_id")
@Column(name = "stock_code", unique = true, nullable = false, length = 20)
public String getStockCode() {
    return this.stockCode;
}

It works really well!

[Thanks to Jejomar Dimayuga for this post http://blog.dagitab.com/htsrv/trackback.php?tb_id=30 which I have modified slightly to use a sequence rather than a table]

  

9 thoughts on “Custom Hibernate Sequence Generator for Id field

  1. Hi your article helps me a lot . Thank you.

    I still have some questions as shown below:

    1. What if I wire hibernate database connection in spring, do I have to still write things like Connection connection = session.connection(); PreparedStatement ps = connection ??
    2. If rs.next() does not return anything, how this situation needs to be processed?

    Thanks

  2. your post was valuable much for me,but i am not using annotations,only the hibenate mapping files.will you explain me how to incorporate your example with hibernate mapping file,
    Thank you very much.

  3. The code lacks closing statements on the result set and prepared statement.
    We got “too many open cursors” in Oracle using it, so close() calles need to be added.

  4. Thanks for the code, just what I was looking for.

    I have a slightly different implementation

    Connection connection = session.connection();
    PreparedStatement ps = null;
    try {
    ps = connection
    .prepareStatement(“SELECT nextval (‘hibernate_sequence’) as nextval”);

    ResultSet rs = ps.executeQuery();
    rs.next();
    Long id = rs.getLong(“nextval”);
    if (log.isDebugEnabled())
    log.debug(“Generating new id:” + id);
    return id;

    } catch (SQLException e) {
    throw new UncheckedException(“Failed to generate new sequence for:”
    + object, e);
    } finally {
    if (ps != null)
    try {
    ps.close();
    } catch (Throwable e) {
    log.warn(“Failed to close statement:” + e.getMessage());
    }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>