If I try to upsert a document with an id and partition key that already exists, it works as expected IF there are no Unique constraints set on the container.
However, when I set any value in the table as Unique, then the upsert doesn't work and I get a (409 conflict - a Document with an id matching the id field of document already exists). The Unique constraint shouldn't be a problem in this case, but it causes this error, which has a strange error description for an upsert because it shouldn't matter if the id already exists.
I'm using documentClient.upsertDocument(collectionLink, documentDefinition, null, true);.
Cosmos DB's Upsert / Replace flow is based on the document's unique identifier (id and Partition Key value), Unique Fields are there to add extra checks for data validation.
When an Upsert operation is made, the service will look for an existing document with the same id and Partition Key value, if there is one, it will update it, otherwise, it will create it.
In your case, you are always sending a new random id, so Upsert is not finding an existing document to update and it's creating a new one every time.
Please define your own id before initiating the Upsert, and set the autogenerate id attribute in the upsert call to it's default (true) value: client.upsertDocument(collectionLink, documentDefinition).
Related
I have an entity that follows this structure:
name: String(not null, unique),
value: Integer(not null)
id: Long(generated, not null, unique)
I have a list of entities(List<>), and I want to save them to a table or update if some were already in a table, but I need an effective way to do that with some bulk/batch insert/update. Now I've tried repository.saveAll and entityManager.merge, but I get the repeated value error, as it doesn't update the values that're already in a table. What should I do?
Please refer to this topic:
How to do bulk (multi row) inserts with JpaRepository?
To get a bulk insert with Sring Boot and Spring Data JPA you need only two things:
set the option spring.jpa.properties.hibernate.jdbc.batch_size to appropriate value you need (for example: 20).
use saveAll() method of your repo with the list of entities prepared for inserting.
What should I do to represent this table in Spring Data Java Persistence Application Programming Interface (JPA)?
The table is specific because it has no primary key and every column in the table can have nulls, and it is read only.
In entity class I can not simply annotate a single column with #id because there is no column with unique values.
I can, of course, create composite virtual primary key in entity class by annotating every column with #id, and that works, but only if there are no nulls in the row. So if I select row(s) with all columns not null then this works. But if one or more columns contains null, Spring is not able to extract that row from table, and instead returns simply null for entire row rather than returning an entity object with only the appropriate field null.
Please do not say "just add id column to the table" because table is read only for us. My company was negotiating for more then a month just to get the read rights to the table! I can not simply add id field in the table.
What else can I do in this case? Other than manually executing a query and extracting the result. Can I somehow fake the id field to make Spring happy? id field is not important for our application, we will never filter the table by id, so it can be whatever makes Spring happy as far as I am concerned.
I don't think there is a way to do that.
Just get a NamedParameterJdbcTemplate injected and query away.
A central premise of JPA is that you can load data from a bunch of tables, edit the resulting object structure and JPA will take note and mirror the changes to the data in the database.
If you don't have anything to use as an id you wouldn't know which row to update. So this whole approach kinda fails to work.
You can use #EmeddedId with an ID you create. Set the ID field either #Transient or static so it won't affect persistence.
In the below example I use the UUID static method .randomUUID() to generate the ID.
So put this into your #Entity and you will get every row regardless of nulls. Inserts will work just fine too (depending on how you disambiguate your rows).
#EmbeddedId
static UUID uuid = UUID.randomUUID();
I am using a postgresql database table which may have inserts with the ID set manually by the user, or need an ID generated using hibernate.
This may lead to the occurrence of generating an ID which has already been inserted into the database manually. Is there any way hibernate can check for collisions between the generated ID and existing IDs?
Hibernate cannot check that, because the sequence is allocated by the database. You could either:
assign negative numbers for manually inserted IDs
use UUID instead of sequences
I am using spring-hibernate-postgres. I have a table say 'some_entity'. It already contains some records.
I have a program that tries to create new SomeEntity object. I am populating that object with appropriate properties, and afterwards I am calling persist() method on it.
In the log, I see that hibernate is trying to get nextVal() from the table sequences. But, nextval that my postgres returns is same as id of 2nd row of some_entity table. So, my hibernate tries to create row with that id. And hence my persist() fails with hibernate constraint violation exception.
May be I am not phrasing the question correctly. I hope someone has already encountered this problem and has resolution for it.
Thanks
I had this problem. I solved it through execution of sql, that updates sequence at application launch
ALTER SEQUENCE names_id_seq RESTART WITH currentId;
,where currentId I get from
SELECT currval('names_id_seq');
I'm working on some old java code, and as part of an insert, the code makes a db call to get the last ID used in a table, then increments the ID, and uses the incremented ID as the next ID to use for the insert, as the PK.
It's a web application, and it seems to me that the same ID could be retrieved on a subsequent get ID call before the first/prior insert is done.
How would I prevent this, to ensure that the same ID is not reused?
Use a transaction in your sql code.
If you Database Server supports the Auto Increment attribute, then you can apply it to the ID column and it will assign itself incrementing unique IDs. The server does all the work and ensures that the ID is valid and unique.