Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GenerationType.UUID #151

Closed
lukasj opened this issue Jul 14, 2017 · 8 comments · Fixed by #319
Closed

GenerationType.UUID #151

lukasj opened this issue Jul 14, 2017 · 8 comments · Fixed by #319
Labels

Comments

@lukasj
Copy link
Contributor

lukasj commented Jul 14, 2017

Modern applications more and more are using replication technologies, inducing the problem of global ID generation.

These systems tend to abstain from central ID algorithms like TABLE or SEQUENCE, but instead of UUIDs as PKs. The benefit is clear: The JVM of the client can produce a UUID super fast even if the network is down, and no PK clash will ever occur.

I think it would be really great particularly for cloud applications if a new GenerationType.UUID would instruct persistence providers to e. g. simply call JRE's UUID.randomUUID() method and prevent any network roundtrips (or providers could decide to ask for UUID from server or JDBC driver by SQL).

This is feasible and very easy to add to EclipseLink.

@lukasj
Copy link
Contributor Author

lukasj commented Jul 14, 2017

@andyjefferson Commented
+1. No brainer. Has been part of DataNucleus since 2010.

@lukasj
Copy link
Contributor Author

lukasj commented Jul 22, 2017

@rbygrave Commented
I'm happy to support this as a nice explicit way of mapping this. As an implementation note in my opinion there is not a strict need for a GenerationType.UUID in that for properties like the ones below the mapping of a UUID generator can safely be assumed automatically.

That is for these properties below:

  @Id 
  UUID id;

or ...

  @Id  @GeneratedValue 
  UUID id;

... it can be automatically assumed from the existence of @Id and being type UUID that this should have a UUID generator associated with the property (and that on insert a UUID value should be set when not supplied).

There is no real downside to this approach and it doesn't require the extra GenerationType.UUID being explicitly mapped.

In my opinion it would be nice for the JPA spec to also push/document this automatically mapped UUID generator approach.

@lukasj
Copy link
Contributor Author

lukasj commented Jul 22, 2017

@mkarg Commented
Rob, this would mix up the way ID is generated (SEQUENCE vs TABLE vs JVM-internal UUID) with actual OR mapping. Hence, you would artifically limit people to the combination "UUID id;" + GenerationType.UUID. But what I want is to keep the freedom JPA provides currently, so one could combine "long id" + GenerationType.UUID or "UUID id;" + GenerationType.SEQUENCE.

@lukasj
Copy link
Contributor Author

lukasj commented Jul 24, 2017

@rbygrave Commented
I'm not sure I fully understand your comment so I'll guess a little.

so one could combine "long id" + GenerationType.UUID

So UUID doesn't really map to a single long value but instead maps to 2 long values. So it is not 100% clear what you are meaning here. With Ebean ORM a "java/logical" UUID can map to a database native UUID, Varchar, or Binary(16). I think you want to support:

  @Id @GeneratedValue(strategy=GenerationType.UUID)
  String id;

And ...

  @Id @GeneratedValue(strategy=GenerationType.UUID)
  byte[] id;

Which is reasonable to me but imo not very good. Once you want to have the single logical model support multiple databases where some databases have native UUID and some don't this mapping is not great - you effectively lose the benefit of native uuid types in databases like Postgres.

So the above is reasonable but I personally think it is flawed.

To be clear, with Ebean ORM we can map a "logical" java.util.UUID type to 3 different DB types being - native UUID, Varchar or Binary. How the java.util.UUID is mapped to the DB is not defined per entity but instead per "database platform" (like a configuration of the entity manager). We can support the single logical model against multiple databases and get the optimal mapping for each.

"UUID id;" + GenerationType.SEQUENCE.

I don't know what this means? It does not make sense to me.

Hence, you would artificially limit people to the combination "UUID id;" + GenerationType.UUID

No, I don't see any limitation actually and have not experienced any limitation to date (this is not a theoretical mapping - I've implemented this and been using it for years in Ebean ORM). That is, if you have a java.util.UUID type an you automatically associate a Generator there are no limitations incurred having done that.

Andy has also implemented UUID support so I'm almost expecting Andy to add in some comments regarding implementation from the DataNucleus perspective.

@lukasj
Copy link
Contributor Author

lukasj commented Jul 24, 2017

@mkarg Commented
Yes, I did not mean long literally, but just as a placeholder for 'other data type', and yes, typically it would be byte[] or String. Whether or not this is good is out of scope of the JPA spec, but solely up to the application programmer. We do not lose the possibilit to support native types, as still you can map to UUID and JPA does not prevent anybody from writing a native mapping in addition to the standard JPA mappings.

"UUID id; + GenerationType.SEQUENCE" means that the Java entity class uses UUID, but a GenerationType.SEQUENCE generator is used to auto-create a primary key. Effectively this would simply use zero as the LSB part and is suitable in situations where the Java application is written newly, but the database schema is legacy -- it exists and must not be changed, e. g. in many scenarios where several (very old) applications access a shared database, and a new Java application is added.

As that scenario is rather common (there are more existing schemas currently in use than new schemas are created, but Java applications are added from time to time), we should not limit the use of UUID to GenerationType.UUID, but must keep open the JPA spec for such "strange" mappings.

@lukasj
Copy link
Contributor Author

lukasj commented Aug 31, 2018

@mkarg
Copy link

mkarg commented Aug 31, 2018

@mkarg I was the original reporter.

@gavinking
Copy link
Contributor

I think it's worth doing this and #152. In Hibernate this looks like:

@Id
@GeneratedValue
UUID id;

And from the discussion above it looks like other products also already support it.

@lukasj Would you like me to write this up for the spec?

gavinking added a commit to gavinking/jpa-api that referenced this issue May 5, 2021
@gavinking gavinking linked a pull request May 5, 2021 that will close this issue
gavinking added a commit to gavinking/jpa-api that referenced this issue Jan 14, 2022
gavinking added a commit to gavinking/jpa-api that referenced this issue Jan 14, 2022
gavinking added a commit to gavinking/jpa-api that referenced this issue Jan 14, 2022
gavinking added a commit to gavinking/jpa-api that referenced this issue Jan 14, 2022
gavinking added a commit to gavinking/jpa-api that referenced this issue Jan 14, 2022
gavinking added a commit to gavinking/jpa-api that referenced this issue Jan 14, 2022
lukasj pushed a commit that referenced this issue Jan 17, 2022
@lukasj lukasj added this to To do in 3.1.0 via automation Jan 17, 2022
@lukasj lukasj moved this from To do to Done in 3.1.0 Jan 17, 2022
@lukasj lukasj added the 3.1.0 label Jan 17, 2022
@lukasj lukasj removed this from Done in 3.1.0 Jan 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants