-1

I need to generate a number of length 12, say variable finalId. Out of those 12 digits, 5 digits are to be taken from another value, say partialid1.

Now finalId = partialId1(5 - digits)+ partialId2(7 digits).

I need to generate partialid2 randomly, where I can use Random class of Java.

Finally i have to insert this finalId in Database, as a Primary key.

So to make sure that newly generated finalId is not existing in Oracle Database, I need to query Oracle Database as well.

Is there any efficient way other than the one i have mentioned above to generate Id in Java and check in database before persisting it?

Curious Techie
  • 185
  • 2
  • 15
  • 1
    You should do some googling before asking a new question. check if this help you out https://stackoverflow.com/a/18228151/2299040 – Sahil Manchanda Jul 27 '17 at 04:14
  • Thank you for the reference but it doesnt help, as i dont have any constraint of time. – Curious Techie Jul 27 '17 at 04:21
  • With time constraint you could generate unique id. Referring to the answer, just put your character limit. – Sahil Manchanda Jul 27 '17 at 04:24
  • Other approach: generate a UUID. Don't check in the database - the chance of a collision is infinitesimal. But put a primary key constraint on the column, so that even in the case where you are the unluckiest person in the universe, you get a mere application error, rather than a corrupt database. – Erwin Bolwidt Jul 27 '17 at 04:44
  • Thanks for the suggestion – Curious Techie Jul 27 '17 at 05:09
  • `finalid` has to be unique. So why does `partialid2` need to be random? Just use a sequence generator and have done with it. – APC Jul 27 '17 at 10:02
  • @APC you are right but it is as per requirement to generate random numbers. Are you suggesting using javax.persistence.SequenceGenerator ? – Curious Techie Jul 27 '17 at 11:51
  • There's a difference between "requirement" and "specification". Requirements are about meeting business needs. What business need does have a random `partialid2` meet that could not be met - and met more efficiently - by using a plain sequence? – APC Jul 27 '17 at 13:00

2 Answers2

1

I would prefer the Java UUID.

You can get the random id using UUID using below code.

String id = UUID.randomUUID().toString().substring(0,7); System.out.println("id "+ id);.

And can append it with your other partial id and have a unique key or primary constraint in DB, depending on the column where you want to store it as suggested by @Erwin.

Note:- we have done it in past for so many primary keys and never had a case where you id collided.

Amit
  • 30,756
  • 6
  • 57
  • 88
1

In general making one id from another has issues because you may be clumping two things together which would be easier just to keep separate. Specifically you may be trying to squeeze a foreign key into a primary key when you could just use two keys.

In any case if you really want to build a semi-random primary key from a stub then I would suggest doing it bitwise because that way it'll be easy to extract the original id in SQL and in Java.

As has been mentioned, if you generate a UUID then you don't really need to worry about checking if it's already used, otherwise you probably will want to.

That said the code for making your ids could look like this:

public class IdGenerator {
    private SecureRandom random = new SecureRandom();   
    private long preservedMask;
    private long randomMask;

    public void init(int preservedBits) {
        this.preservedMask = (1L << preservedBits) - 1;
        this.randomMask = ~this.preservedMask;
    }

    public long makeIdFrom(long preserved) {
        return (this.random.nextLong() & this.randomMask) | (preserved & this.preservedMask);
    }

    public UUID makeUuidFrom(long preserved) {
        UUID uuid = UUID.randomUUID();
        return new UUID(uuid.getMostSignificantBits(), (uuid.getLeastSignificantBits() & this.randomMask) | (preserved & this.preservedMask));
    }

    public boolean idsMatch(long id1, long id2) {
        return (id1 & this.preservedMask) == (id2 & this.preservedMask);
    }
}

Essentially this preserves a number of least significant bits in your original. That number you need to specify when you call init.

Evan Jones
  • 876
  • 4
  • 9
  • Thanks for the answer. – Curious Techie Jul 27 '17 at 05:49
  • It's an bad idea to use a normal java.util.Random to generate UUID's. For one it has only a 48-bit seed, which you are using to generate a 64-bit random number - but it can only generate 2^48 different random values at most. You should use SecureRandom. – Erwin Bolwidt Jul 27 '17 at 05:55
  • Also interestingly if you look at the source for UUID bytes 7 and 9 are adjusted. I think I need another edit. – Evan Jones Jul 27 '17 at 06:13