3

I have an entity which is used uuid as PRIMARY KEY and it is generated

@Id
@Column(name = "uuid")
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
private UUID uuid;

How can I tell Hibernate to use an explicit value or can I modify the value Hibernate generated?

Edit: My problem is that, in most cases, it's fine that the value is generated but in some cases, I want to create an entity with an explicit uuid.

My workaround (aslo suggested by Dipali Vasani below)

@Id
@Column(name = "uuid")
private UUID uuid;
/**
 * if defined, this will be used instead of the generated one
 */
private transient UUID preferredUuid;

@PrePersist
private void initializeUuid() {
    if (preferredUuid != null) {
        uuid = preferredUuid;
    }
    else {
        uuid = UUID.randomUUID();
    }
}
0

1 Answer 1

1

Option 1: refer this question :

Does JPA have something like hibernates '@GenericGenerator' for generating custom ids?

and the answer :

https://stackoverflow.com/a/7462096/1982680

they have used @PrePersist

you can use it like :

  @PrePersist
  public void ensureUuid() {
    uuid= ...
  }

Option 2 : Creating Custom Sequence

import java.util.UUID;
import java.util.Vector;

import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sessions.Session;

public class UUIDSequence extends Sequence implements SessionCustomizer {

    public UUIDSequence() {
        super();
    }

    public UUIDSequence(String name) {
        super(name);
    }

    @Override
    public Object getGeneratedValue(Accessor accessor,
            AbstractSession writeSession, String seqName) {
        return UUID.randomUUID().toString().toUpperCase();
    }

    @Override
    public Vector getGeneratedVector(Accessor accessor,
            AbstractSession writeSession, String seqName, int size) {
        return null;
    }

    @Override
    protected void onConnect() {
    }

    @Override
    protected void onDisconnect() {
    }

    @Override
    public boolean shouldAcquireValueAfterInsert() {
        return false;
    }

    @Override
    public boolean shouldOverrideExistingValue(String seqName,
            Object existingValue) {
        return ((String) existingValue).isEmpty();
    }

    @Override
    public boolean shouldUseTransaction() {
        return false;
    }

    @Override
    public boolean shouldUsePreallocation() {
        return false;
    }

    public void customize(Session session) throws Exception {
        UUIDSequence sequence = new UUIDSequence("system-uuid");

        session.getLogin().addSequence(sequence);
    }

}

Registering Sequence

customizer can be specified as a persistence unit property in API:

properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER,
                "eclipselink.example.UUIDSequence");

or in XML :

<property name="eclipselink.session.customizer" value="eclipselink.example.UUIDSequence"/>

Using the Sequence

@Id
@GeneratedValue(generator="system-uuid")
@Column(name="uuid")
private UUID uuid;
Sign up to request clarification or add additional context in comments.

3 Comments

thanks. I'm using option 1 as well. Do you know when the generation happens? It seems it happens after @PrePersist, so to use option 1, we need not to decorate the field with any generator.
@PrePersist is a callback which is Executed before the entity manager persist operation is actually executed or cascaded. and it is synchronous with the persist operation. so you can go with it.
Option 2 will not work for me. Maybe my question is not clear yet. Basically in most cases, it's perfectly fine that the value is generated but in a few cases I want to create an entity with an explicit uuid. So there's no way to modify the value once it's generated?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.