Sequence Vs Auto increment - spring

I understood why do i use Sequence when i want to auto increment, however, why do i have to do all that setting when using postgresql. in mysql all that i have to do is diclear that the field will be primary key and AutoIncrement and the job done. in Spring boot Java and postgres i need to create a lot of setting
for example the code bellow. can someone please help me understand why do i have to go through all this long process.
#Id
#SequenceGenerator(
name = "owner_sequence",
sequenceName ="owner_sequence",
allocationSize = 1
)
#GeneratedValue(
strategy = SEQUENCE,
generator = "owner_sequence"
)

In short, sequences gives a more flexibility. Backside - writing more code. Sequences are useful when developing non trivial, complex projects like replication systems. Sequences are nice when you will need manual management of your "id" fields numbering and allows to automate many things in database.
Some usage example:
create sequence test_id_seq;
create table test(field1 int not null default nextval('test_id_seq'));
ALTER SEQUENCE test_id_seq RESTART WITH 1;
UPDATE t SET idcolumn=nextval('test_id_seq');

Related

Randomly generated public unique ids

Currently I'm generating unique ids for rows in my database using int and auto_increment. These ids are public facing so in the url you can see something like this https://example.com/path/1 or https://example.com/path/2
After talking with another engineer they've advised me that I should use randomly generated ids so that they're not guessable.
How can I generate a unique ID & without doing a forloop on the database each time to make sure it's unique? e.g. take stripe for example. All of their ids are price_sdfgsdfg or prod_iisdfgsdfg. Whats the best way to generate unique ids for rows like these?
Without knowing which language or database you're using, the simplest way is using uuids.
To prevent downloading all existing database unique keys, and then for looping over them all, simply just try to INSERT INTO whichever table you are using.
If the result fails (e.g. Exception), then the row is taken, continue.
If the result passes, break loop.
This only works when you have a column which is NOT NULL, and UNIQUE.
That's how I "know" without looping over the whole database of IDs, or downloading them into local memory, etc.
Using auto_increment wont lead to duplicates because when a SQL or no-SQL table is in use, it will be locked and given to the next available number in the queue, which is the beauty of databases.
SQL example (mySQL, SQLite, mariadb):
CREATE TABLE `my_db`.`my_table` ( `unique_id` INT NOT NULL , UNIQUE (`unique_id`)) ENGINE = InnoDB;`
Insert a unique_id
INSERT INTO `test` (`unique_id`) VALUES ('999999999');
Great, we have a row
INSERT INTO `test` (`unique_id`) VALUES ('999999999');
If not, then retry:
Error:
#1062 - Duplicate entry '999999999' for key 'unique_id'
If these are public URLs, and the content is sensitive, then I definitely do not recommend int's as someone can trivially guess 1 through 99999999... etc.
In any language, have a look at /dev/urandom.
In shell/bash scripts, I might use uuidgen:
9dccd646-043e-4984-9126-3060b4ced180
In Python, I'll use pandas:
df.set_index(pd.util.hash_pandas_object(df, encoding='utf8'), drop=True, inplace=True)
df.index.rename('hash', inplace=True)
Lastly, UUID's aren't perfect: they are only a-f 0-9 all lowercase, but they are easy to generate: every language has one.
In JavaScript you may want to check out some secure Open Source apps, for example, Jitsi: https://github.com/jitsi/js-utils/blob/master/random/roomNameGenerator.js where they conjugate word:
E.g. Satisfied-Global-Architectural-Bitter

Auto Increment the Primary Key in Berkeley Database Java Edition

I want to auto increment the Primary Key in Berkeley Database. I use #PrimaryKey(sequence="Id"). It worked fine. but when i enter a another data the sequence is getting wrong. As a Example when i execute database.put the primary key is "1", but next time it is "101" and next time it is "201". This is my code. are there any thing to add. I+ didn't use SequenceConfig config = new SequenceConfig(); config.setAllowCreate(true);. Do i need to use it. Please help me.
#PrimaryKey(sequence="ID")
long id;
String name;
Login_Audit(String name)
{
this.name = name;
}
The sequence would only be wrong if it ever returned the same value twice. There's no requirement that values of a sequence should be consecutive, nor should you ever rely on them being so. The reason you're not getting consecutive numbers is probably the way BDB JE handles multi-threading efficiently: opening a handle to a sequence will "pre-allocate" a range of values to be used exclusively by that handle, so that it can give you new values without having to do an expensive database lock operation every time.
You can either just not care about the actual values of your IDs (this is the preferred option) or open the sequence manually using Database.openSequence() and manipulate it directly.

JBoss EAP 6.x with Hibernate Oracle Sequence Duplicate Value on Primary Key

I have defined a number of Hibernate Entities using pure JPA annotations. These use an predefined Oracle Sequence on my database to automatically generate primary key values.
#Id
#SequenceGenerator(name = "USERS_ID_GENERATOR", sequenceName = "MY_SEQ")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_ID_GENERATOR")
#Column(name = "U_ID", updatable = false, unique = true, nullable = false, precision = 19)
private Long id;
When this is deployed to JBoss EAP 6.1 all works well initially however after a short period Hibernate starts generating duplicate keys on inserts (ORA-00001 errors).
I don't care about id ordering or gaps, but can't tolerate duplicate keys... What is going on here?
This is not well documented, many of the solutions on here and other sites relate to older versions of hibernate where the HiLo sequenceGenerator was the default. But after investigation I found the underlying cause is that JBoss EAP 6 sets
hibernate.id.new_generator_mappings=true
by default, which uses an org.org.hibernate.id.enhanced.SequenceStyleGenerator instead of the older version.
The Hibernate SequenceStyleGenerator default increment is 1 (check the code!), however JPA overrides the increment value in this generator to 50. This means that the Generator looks at the sequence nextval and keeps a cache of 50 ids to use, starting from nextval - 49. When these are exhausted the generator reads the next sequence from oracle, and repeats the process. So once the first series of ids are exhausted we start seeing duplicate keys.
So the resolution is:
1) Either define your Oracle sequence(s) with an increment value of 50 to match the JPA default
CREATE SEQUENCE MY_SEQ
START WITH 50
MAXVALUE 9999999999999999999
INCREMENT BY 50
NOCYCLE;
or
2) Add allocationSize=1 to the #SequenceGenerator annotation - this forces the SequenceGenerator to go back to read the next value from the oracle sequence for each ID it requires (with a potential performance impact)
#SequenceGenerator(name = "USERS_ID_GENERATOR", sequenceName = "MY_SEQ", allocationSize = 1)
, or
3) define the Oracle sequence INCREMENT BY some other value, and ensure the allocationSize matches.
Answered my own question in the hope of helping others that strike this issue.
Your answers are correct; just some more details.
Some posts propose to turn off
hibernate.id.new_generator_mappings=false.
But according to
https://docs.jboss.org/author/display/AS71/JPA+Reference+Guide#JPAReferenceGuide-Persistenceunitproperties
There is a difference between
GenerationType.AUTO and GenerationType.SEQUENCE
if you choose AUTO, you'll select the hibernate native.
and if you choose SEQUENCE, you'll match hilo algorithm for sequence allocation that is absolutely not the same as SequenceStyleGenerator.
This will be NOT compatible if you switch hibernate.id.new_generator_mappings=true / false.
So the answer 1) is definitely the correct one / following the current Hibernate/Jboss recommendations.
...and the answer setting allocationSize=1 to all entities is not a good solution.
See
http://itdevworld.wordpress.com/2009/12/20/hibernate-sequencegenerator-with-allocationsize1-leads-to-huge-contention/

Is there any way to generate an ID without a sequence?

Current application use JPA to auto generate table/entity id. Now a requirement wants to get a query to manually insert data in to the database using SQL queries
So the questions are:
Is it worth to create a sequence in this schema just for this little requirement?
If answer to 1 is no, then what could be a plan b?
Yes. A sequence is trivial - why would you not do it?
N/A
Few ways:
Use a UUID. UUIDs are pseudo-random, large alphanumeric strings which are guaranteed to be unique once generated.
Does the data have something unique? Like a timestamp, or IP address, etc? If so, use that
Combination of current timestamp + some less unique value in the data
Combination of current timestamp + some integer i that you keep incrementing
There are others (including generating a checksum, custom random numbers instead of UUIDs, etc) - but those have the possibility of overlaps, so not mentioning them.
Edit: Minor clarifications
Are you just doing a single data load into an empty table, and there are no other users concurrently inserting data? If so, you can just use ROWNUM to generate the IDs starting from 1, e.g.
INSERT INTO mytable
SELECT ROWNUM AS ID
,etc AS etc
FROM ...

Enterprise Architect Oracle long field column properties

I have a little problem with Enterprise Architect by Sparx System.
Im trying to model database schema for Oracle. I created table with primary key with data type long. But when im trying to modify column properties (set AutoNum = true) I see empty properties. I read documentation of EA and saw that I need to setup this property to generate sequence syntax.
When I change data type to number, or switch database to mysql (for example) everything is alright, there are properties so Im able to modify AutoNum value.
Did you had similar problem and found solution ? or maybe im doing something wrong.
regards
It's becouse Oracle use sequence instead of autoincrement option. I've checked it and I think you have to use NUMBER column type and then set AutoNum property (you have to select Generate Sequences in options to get proper DDL code too). Instead of LONG data type you can set PRECISION and SCALE options on NUMBER type ie NUMBER(8) mean you can have 8 digits number and it can be set up to 38, so if you don't want to store info about every star in the universe will be enought for your scenario :)

Resources