2

I'm preparing a Java library that need to assign a unique id to the generated objects for serialization purposes. Once a unique id is generated, I have to ensure that the next time I use the library, there is no possibility to reassign an id to an object that I already saved in the past.

Now, I see that many in Stackoverflow suggest to rely on a couple of options, i.e. UUID, SecureRandom, but I'm not sure that this classes suits my needs and I'm not sure about how to use them.

Please, can you address myself to the right utility to use and how to generate the id?

Solutions based on utility from Guava/Apache are welcome.

mat_boy
  • 12,998
  • 22
  • 72
  • 116
  • 1
    Why dont you use an atomic long ? It can get you the [next value](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicLong.html#incrementAndGet()) in a thread safe manner. A database sequence may also do. Are these IDs assigned from the same machine ? How fast should they be ? Are alpha numeric IDs required ? – Deepak Bala Apr 25 '13 at 09:31
  • I will answer in order. A1) To my knowledge, AtomicLong are only a thread-safe version of Long, hence I have no guarantee than when I use the library in a second time the new int is unique. A2) Id assignment are in theory from the same machine, but what happens if I deserialize object saved from another machine? A3)Fast, I have no request about efficiency. A4) Is not really important! What is important is that they must be unique. – mat_boy Apr 25 '13 at 09:49
  • Your observation about `AtomicLong` and losing the last sequence on restart are correct. If you need a unique ID across multiple invocations of a program, use a database sequence. You can ask the DB to cache the next N numbers of a sequence to make it reasonable fast and the value will be persisted across invocations. – Deepak Bala Apr 25 '13 at 09:56
  • @DeepakBala So, I should embedd such a DB, like Apache Derby, in my application. Or, otherwise, I need to save the last id into a file. Isn't it? But what about UUID and SecureRandom? People says great things about these classes! – mat_boy Apr 25 '13 at 10:03
  • The probability of generating duplicate UUIDs is [pretty low](http://en.wikipedia.org/wiki/UUID#Random%5FUUID%5Fprobability%5Fof%5Fduplicates). I'm unaware of the probability that 2 UUID instances across different machines generate the same ID, but then UUIDs should be unique across JVMs. I would not go through the trouble of embedding a database just to generate UUIDs. You can use a java `UUID` safely. I thought the DB might be convenient if say you wanted to know how many IDs were generated etc. – Deepak Bala Apr 25 '13 at 11:18
  • I concur with those who suggest using UUID. You won't need to persist anything, since UUIDs are unique forever. UUID has proper equals and hashCode methods, so it can be used as a key in Maps, and it is serializable. Creating one is done with `UUID.randomUUID()`. If you need to store it in a file or in a database that doesn't directly support UUIDs/GUIDs, you can safely convert it to a string with `toString()` and convert it back using `UUID.fromString(s)`. – VGR Apr 25 '13 at 11:21
  • @VGR I read [here](http://stackoverflow.com/questions/325443/generate-uuid-in-java) that there is no guarantee that UUID will avoid id collisions. – mat_boy Apr 25 '13 at 11:32
  • As Deepak Bala points out, the likelihood of collision is extraordinarily low. His Wikipedia link explains the odds: It is more likely that you will be hit by a meteorite than encounter a single collision among 70 trillion random UUIDs. UUIDs were designed to make the likelihood of collisions so infinitesimal that it can be treated as zero. – VGR Apr 25 '13 at 16:53
  • @DeepakBala Please, can you post a full answer with all the details from your comments, so that I can accept it? – mat_boy Apr 25 '13 at 17:23
  • @mat_boy Done. I've moved the content to an answer. – Deepak Bala Apr 26 '13 at 09:59

2 Answers2

2

The probability of generating duplicate UUIDs is pretty low. I'm unaware of the probability that 2 UUID instances across different machines generate the same ID, but then UUIDs should be unique across JVMs. I would not go through the trouble of embedding a database just to generate UUIDs. You can use a java UUID safely.

Alternate solution

If you need a unique ID across multiple invocations of a program, use a database sequence. You can ask the DB to cache the next N numbers of a sequence to make it reasonable fast and the value will be persisted across invocations. UUIDs are more convenient to use, but both solutions will work. If you use a DB, you will get to know the number of object you've serialized.

Deepak Bala
  • 11,095
  • 2
  • 38
  • 49
0

If your objects need a unique number, then why not just do a sequence. You would have to code a custom class that did the following:

  • It would be a singleton
  • Found the last value used by an object on startup
  • Had a method like getNext, that incremented the lastValue and returned the value to be used by the object.
  • Make it thread safe.
Pete B.
  • 3,188
  • 6
  • 25
  • 38
  • But this is not secure when I run the same library twice at the same time, e.g. on the same computer. In fact, each class will read the last id, then they will assign sequential ids and on save I will find serialized objects with identical ids! I believe that Deepak bala got the point. I should use an inner DB, it will act as a synchronization point between multiple applications. Not the fastest solution, but doesn't really matter! – mat_boy Apr 25 '13 at 10:10