简体   繁体   中英

Hibernate: is it possible to modify generated value?

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();
    }
}

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM