spring-attic / spring-cloud-gcp

Integration for Google Cloud Platform APIs with Spring
Apache License 2.0
704 stars 694 forks source link

Datasource UUID Key #2555

Closed beunick closed 3 years ago

beunick commented 3 years ago

First of all thanks for putting this code. Very useful. I am new with DataStore Key. I was wondering how I can define my Key to use UUID ?

For example in the Instrument.java class, how to make sure the Key object use UUID ?

https://github.com/spring-cloud/spring-cloud-gcp/blob/8200d7cfcf6e0a29c5004559bd16666f5dc43e57/spring-cloud-gcp-samples/spring-cloud-gcp-data-datastore-sample/src/main/java/com/example/Instrument.java#L35

meltsufin commented 3 years ago

@beunick Thanks for the kind words! You can change the type of the @Id to String and then assign a UUID to it. String instrumentId = UUID.randomUUID().toString(); Does that answer your question?

cc/ @dmitry-s

beunick commented 3 years ago

@dmitry-s Thanks for the note. When I try that I have this error message :

Caused by: org.springframework.cloud.gcp.data.datastore.core.mapping.DatastoreDataException: Cloud Datastore can only allocate IDs for Long and Key properties. Cannot allocate for type: class java.lang.String

beunick commented 3 years ago

Here is my code:

            @Id
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = UUID.randomUUID().toString();
    }

Here is my dependency in my POM.xml: `

org.springframework.cloud
        <artifactId>spring-cloud-gcp-starter-data-datastore</artifactId>
        <version>1.2.5.RELEASE</version>
    </dependency>`

And I got this error:

Caused by: org.springframework.cloud.gcp.data.datastore.core.mapping.DatastoreDataException: Cloud Datastore can only allocate IDs for Long and Key properties. Cannot allocate for type: class java.lang.String

meltsufin commented 3 years ago

Since setId() will probably never be called, this isn't going to work. After you create the object, you can set the id.

Instrument instrument = new Instrument();
instrument.setId(UUID.randomUUID().toString());
dmitry-s commented 3 years ago

@beunick I think you can assign UUID in the constructor

class YourClass {
...
    public YourClass() {
        this.id = UUID.randomUUID().toString();
    }
...
}

or along with field declaration:

@Id
private String id = UUID.randomUUID().toString();

Let us know if that helps.

Thanks!

dmitry-s commented 3 years ago

@beunick BTW if you don't necessary need UUID, but would like Datastore to allocate a Long id for you, you could just switch to:

@Id
Long id;

And if it is null when you save your entity, the id is allocated automatically.

beunick commented 3 years ago

Hi @dmitry-s, Thank you so much for your assistance. Indeed you are right, thanks for the solution. I am new with noSql gcloud Datastore with SpringBoot and still learning. Thanks. I am now able to use Key and set UUID in the key this way:

Datastore datastore = DatastoreOptions.getDefaultInstance().getService()

    Key id = datastore.newKeyFactory()
            .setKind("kind_name")
            .newKey(UUID.randomUUID());

            Instrument instrument = new Instrument();
            instrument.setId(id)`

It seems to be working pretty good. I hope I am doing it right though :)

Thank You. Cheers,

dmitry-s commented 3 years ago

@beunick that should work, however I think it's better to use String UUID instead of Key. This way you don't need to worry about getting a Datastore instance, creating a KeyFactory and other low level details.

We do not recommend using Keys directly if you can avoid it.