I have an app where I want to save some entities which have some fields. I used liquibase to add some when the application starts. The problem is that when I try to save a new one Hibernate tries to give to it the id 1 but this id already exists in the database. How can I make hibernate aware of liquibase inserts?
It depends what is your ID generation strategy. If you are using a sequence simply set the initial value of the sequence to 10,000. This will allow you to insert up to 10,000 records with Liquibase.
For example if you are using PotgreSQL you can do
ALTER SEQUENCE sequence_name
MINVALUE 10000
START 10000
RESTART 10000;
Related
After truncating my database and re-insert it with script my spring doesn't refer to the latest data anymore. But somehow when I create new user, the hibernate still create user id as 1, which in fact already existed after I committed my script. Refreshing or restarting project won't help. Any ideas ? Thanks
Databases like oracle maintain the sequence buffer for the primary key, you will have to set your sequence number in the sequence table then it will start generating the primary key to the next number in the sequence.
In Postgres also you can do the same and this will solve your problem.
I need a help on persisting an entity in a Oracle DB table that uses trigger and sequence for PK.
By now, I tried these from other stackoverflow questions:
#Id
#GeneratedValue(generator="increment")
#GenericGenerator(name="increment", strategy="increment")
This approach works. It finds the max value of PK and increment the value in 1. But, this doesn't update the Db sequence causing "constraint violation" error at some point.
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="id_sequence")
#SequenceGenerator(name="id_sequence", sequenceName="MY_DB_SEQ")
This approach doesn't work for me either. Sadly, the Db sequence is not accessible and causing error when it is trying to run internally "select MY_DB_SEQ.nextval from dual". Why is not accesible? Go and ask DB admin :)
It looks like the only option I have is passing null in the Entity PK attribute so that the DB trigger, which uses the a DB sequence to get the nextval when the ID is null, assigns the PK value in DB record.
How can I pass a null value for #Id? Of course this is throwing error because is needed. Is there any other annotation I can use for this?
If this is not possible, what other ways I should try?
Thanks for your help.
UPDATE
I couldn't find another way for this, having a DB Seq that is not accessible for user, and when it requires to pass NULL to PK in order to have DB use the trigger which check NULL value in PK to run seq nexval.
After granting access to DB Seq, this approach of course works.
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="id_sequence")
#SequenceGenerator(name="id_sequence", sequenceName="MY_DB_SEQ")
Did you create the sequence in the database as below?
CREATE SEQUENCE id_seq INCREMENT BY 1 START WITH 0 MINVALUE 0 MAXVALUE 100 NOCYCLE NOCACHE;
if not create first.
or else add the below properties in the application but it's not good practice.
spring.jpa.hibernate.ddl-auto = update
As of now, I couldn't find any solution to pass NULL to PK in Entity.
In DB, the DB Sequences were granted access. Spring Boot can now read the sequence and gran the next value.
i m using spring data saveAll to save 3500 records in an Oracle database but it execute very slowly, is there a way to do bulk insert or any other fast way
noteRepository.saveAll(noteEntityList);//<- this one is slow for 3000 records
thanks in advance
By default, saveAll does not create batch, the batch processing needs to be enabled.
You need to set below properties to enable batch processing
spring.jpa.properties.hibernate.jdbc.batch_size=100
spring.jpa.properties.hibernate.order_inserts=true (if inserts)
OR
spring.jpa.properties.hibernate.order_updates=true (if updates)
First property collects the transaction in batch and second property collects the statements grouped by entity.
Check this thread for more details
How to do bulk (multi row) inserts with JpaRepository?
Also, if you want to do batch inserts, make sure that if your table has an auto-incremented column (say as a PK), that its set up as a Sequence (not Identity) and that the allocationSize (Java) and increment_by value (DB Sequence) are set to the batch size you are trying to persist. Don't set those values to one, else insert will still be slow as JPA will need to keep going back to the DB to get the next value from the sequence.
I'm trying to auto-generate ID's for my entity, but it's not generating. Instead, it's starting from 1 when there already exists an entry with id "1" in my DB. Why is it not generating id "9" for my new entity?
Typically when creating a table with GenerationType.IDENTITY on postgres, Hibernate will setup the id column plus a database sequence to manage this id.
By convention the sequence name will be "tablename_id_seq". E.g., for the table ad_group_action there will be a corresponding sequence ad_group_action_id_seq. You can connect to the database to double-check the actual sequence name created.
The sequence just starts from 1 and increments each time a row is inserted by Hibernate.
But if there are pre-existing rows -- or if rows with existing IDs are inserted "manually" into the table -- those rows can conflict with the sequence.
One solution is to simply reset the sequence (from pgAdmin or another database client) to start at a higher number (say 100), using something like:
ALTER SEQUENCE ad_group_action_id_seq RESTART WITH 100;
Now Hibernate will not conflict with the existing rows (assuming their max id is < 100).
Alternatively, when inserting rows manually, omit the id column and let postgres automatically set them. This way the table and the sequence will always be in sync.
I have few tables in my database where the primary keys are auto generated using Hibernate seqhilo generator configuration. We need to archive these records and at a later point, should be able to restore them in case of a business scenario. My question is if I restore these tables with simple insert statements will that suffice or should I worry about the sequence generator? I would like to have the same ID and not a new generated one. To be clear these re-inserts will happen via direct SQL and not via Hibernate.