6

I use hibernate sequences to generate id of an entity. I use PostgreSQL 9.1.

Is it possible to get entity id before it is saved to database? How?

everton
  • 7,579
  • 2
  • 29
  • 42
VB_
  • 45,112
  • 42
  • 145
  • 293

3 Answers3

4

You explicitely create a separate sequence, get its value, then insert an object with id based on that value. You will have more code, but the ID will be available before the insertion and the guarantees for sequences are exactly the same as for serially given IDs, because they are essentially the same.

In other words:

  • create your own sequence
  • make a primary key a simple int not serial
  • get a number from sequence
  • use it as an ID for your object

This question has an answer saying how to get next sequence value.

Community
  • 1
  • 1
Dariusz
  • 21,561
  • 9
  • 74
  • 114
2

save() method returns the id of the entity that is saved. You can use it!

reference:-> http://docs.jboss.org/hibernate/annotations/3.5/api/org/hibernate/Session.html

Vijay
  • 213
  • 1
  • 9
  • 7
    This is not what the OP asked for - the requirement was 'before it is saved' – kostja Dec 20 '13 at 12:04
  • 5
    But the fact is that save() doesn't actually save the entity. It's only saved at the next flush (implicit or implicit) – JB Nizet Dec 20 '13 at 12:09
0

You can implement the interface org.hibernate.id.IdentifierGenerator and create a Id generator.

Example:

import com.fasterxml.uuid.Generators;
import com.fasterxml.uuid.impl.TimeBasedGenerator;

public class TimeBasedIDGenerator implements IdentifierGenerator {

    private static TimeBasedGenerator generator = Generators.timeBasedGenerator();

    private static TimeBasedIDGenerator SINGLETON = new TimeBasedIDGenerator();

    public static UUID generate() {
        return SINGLETON.generateUUID();
    }

    @Override
    public Serializable generate(SessionImplementor session, Object parent) throws HibernateException {
        return generator.generate();;
    }
}

This can be used in your Entities like this. So the id is generated by the constructor:

@Entity
public EntityClassName {

     private UUID uuid;
     private Integer mandatoryField;

    public EntityClassName() {
    }

    public EntityClassName(Integer mandatoryField) {
        this.uuid = TimeBasedIDGenerator.generate();
         this.mandatoryField = mandatoryField;
    }


    @Id
    @Column(name = COLUMN_XXX_UUID)
    @Type(type = "java.util.UUID")
    public UUID getUuid() {
        return uuid;
    }

    // setter + other properties

}
K.C.
  • 2,084
  • 2
  • 25
  • 38
  • This implementation will give your entity a new ID on each read from the DB as hibernate calls the default constructor via reflection. It seems that somehow you miss the point of hibernate's IdentifierGenerator. – lost Mar 29 '14 at 00:23
  • Indeed, the call to generate a new id must not be in the default constructor but in an other constructor. I'll modify my post. – K.C. Mar 29 '14 at 07:11