3

I have an entity called Booking, which has a generated id field what I use as primary key. It works fine. I want to add another field, uuid which I'll use as resource identifier in a REST API. I have a Postgres DB and set up the field to be auto generated:

uuid character varying(36) not null default uuid_generate_v1mc()

On creation, the DB generates the id and uuid just fine, but in the Java code, the uuid field is null. My entity looks like this:

@Entity
public class Booking {

    @Id
    @SequenceGenerator(name="booking_id_seq", sequenceName="booking_id_seq", allocationSize=1)
    @GeneratedValue(strategy= GenerationType.IDENTITY, generator = "booking_id_seq")
    private Long id;

    @Column(nullable = false)
    private String uuid;
(...)
}

What am I doing wrong?

Follow up: Thank you for everybody for the comments and answers. It looks like I have two choices, either reload the entity from the DB to have the uuid generated by the DB or generate it myself in the code. Which one is preferred? I guess the latter is more performant, but is there anything else to consider?

2
  • 2
    Only the @Id field is automatically synchronized with the DB other generated fields aren't. You will have to reload the entity from the db. Commented Jun 25, 2017 at 19:20
  • 1
    Only the id is generated. uuid is not an id and thus is not generated automatically, You have to set a value since the field is not nullable. Commented Jun 25, 2017 at 19:22

2 Answers 2

5

you can do a fill with @PrePersist in your entity class

@PrePersist
public void autofill() {
    this.setUuid(UUID.randomUUID().toString());
}

i created an example project for your question https://github.com/zz-chen/Sample-spring-data-jpa-generate-uuid

you can run it with command

gradle bootRun

and you will get some message like this

2017-06-26 11:12:16.118 INFO 78681 --- [ main] hello.Application : Customer found with findOne(1L): 2017-06-26 11:12:16.119 INFO 78681 --- [ main] hello.Application : -------------------------------- 2017-06-26 11:12:16.120 INFO 78681 --- [ main] hello.Application : Customer[id=1, firstName='Jack', lastName='Bauer',uuid='44969325-c31f-4b8e-96d6-a59ff9b845b6'] 2017-06-26 11:12:16.122 INFO 78681 --- [ main] hello.Application : 2017-06-26 11:12:16.122 INFO 78681 --- [ main] hello.Application
: Customer found with findByLastName('Bauer'): 2017-06-26 11:12:16.122 INFO 78681 --- [ main] hello.Application
: -------------------------------------------- 2017-06-26 11:12:16.158 INFO 78681 --- [ main] hello.Application
: Customer[id=1, firstName='Jack', lastName='Bauer',uuid='44969325-c31f-4b8e-96d6-a59ff9b845b6'] 2017-06-26 11:12:16.158 INFO 78681 --- [ main] hello.Application : Customer[id=3, firstName='Kim', lastName='Bauer',uuid='0cef24ad-ce97-4c79-b8a4-69ff575326fb']

with the message we can confirm that the uuid field works perfect !!!

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I ended up using your solution, because I think using PrePersist is more elegant.
1

You will only need to add the following on the field in your entity:

import java.util.UUID;

@Column(unique = true, name = "uuid", nullable = false)
private String uuid = UUID.randomUUID().toString().toUpperCase();

1 Comment

I don't think this is a good solution, if we are reading from the database, when JPA read each record and serialize it into an object, what it does is to create an object using the default empty constructor, then uuid = UUID.randomUUID().toString().toUpperCase() will be executed unnecessarily, although the value will be overwritten with the one from the DB by the JPA serializer, the first is not cheap in terms of processor consumption

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.