I am running a Spring Boot application were I use JPA. I am using Postgresql as DB.
I get some data from an api where there is no Id for each row. So I have to use #Id and #GeneratedValue. But my problem is that when I request this data again I might get the exact same rows or some of them again. I can make a composite key that consist of 3 of the columns but then how do I do with the Id that I would like to keep (autogenerated value). If I understand correct, I can´t use composite primary key and a generate #Id at the same time?
An extension of this question is that sometimes a column in each row are updated. Then I would like to update only this column and not create a new row in the DB.
I could make a modified query that checks if the three column (composite key) already exist then I update that row if any change or if row is missing just save. Or is their any other option that I have missed so I do not have to write any query myself?
You are correct, you have to decide if you want to use a single autogenerated Id or a composite key, you can't have both at the same time. And if your API can't handle a single Id you are probably better of doing as you are thinking in your extended question; creating a composite key and when updating rows check for a row that match your three values.
Related
l have a table without a Primary Key or Unique Key column. I need to manipulate this table from the Spring application by using JPA and Hibernate.
While I was trying to map this table’s entity, it fails because there's no #Id mapping.
I tried to make a composite id from all the entity properties to ensure uniqueness, but in this case, the entity has returned an immutable object.
I need to manipulate some variables of this entity. What should I do? To alter the table by adding a unique column will bring me new challanges. Is there a way without altering table?
Let's assume you wanted to change those records with SQL. How would you know which row to update or delete if you don't have a unique column?
Unless you create a unique column, there's nothing you can do about it.
There should be a unique way to identify your records. Sometimes, you have multiple columns. In this case, you use a composed primary key. In JPA, you can implement a composed primary key in two ways: #EmbeddedId or #IdClass.
I have an entity with autogenerated id value and I am using MySQL DB
entity definition
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
table column definition in MYSQL
id bigint not null auto_increment
And I had to copy data to the table from external and I want to continue generating entities and save them, But seems in JPA side it generates id values which already have in the DB (which are copied from externally)
Is there any way to tell JPA, generate next id from whatever in MySQL table?
And when I use both autogenerating from JPA side and auto-increment column in DB side, how internally it works, which side gets the priority?
GenerationType.IDENTITY is not the best way of use, due to a lack of performance it involves. The way it work is that it relies on an auto-incremented database column and lets the database generate a new value with each insert operation, so there would be a sequence in DB which generates the values.
But here comes the problem: if you use Hibernate, it requires a primary key value for each managed entity, so it has to perform the insert statement immediately to be able to work. This avoid the use of JDBC batching optimization.
And when I use both autogenerating from JPA side and auto-increment
column in DB side, how internally it works, which side gets the
priority?
The #GeneratedValue(strategy=GenerationType.TABLE) indicates the provider to use a table to get the IDs when inserting new entities into the database.
When using Hibernate as provider, you will find a table called hibernate_sequences with two columns: entity name and max identity already assigned to this entity.
Hope this helps.
Is there a way to tell Hibernate to first check if the current primary key generated by a Table Generator is usable or outdated?
I have an application which uses hibernate to create new entries in several tables in my database, but sometimes these generated values are outdated and already used. This happens because this database is used by quite a few applications and scripts, and some of these use the "select MAX(ID)+1"-Keygeneration"strategy". It is not really an option to change all other components to use the table generator (although it would solve the problem), so I have to make sure that the values I get from the table generator are really usable.
Is there any way to tell Hibernate to check the validity of the generated values before it tries to insert a new record into the database (and throw a ConstraintViolationException)?
Or, alternatively, is there a way to manually update the generator tables before hibernate uses them to generate new Ids?
The obvious way would be to run a native query like UPDATE pk_generator SET value=(SELECT MAX(ID)+1 from members) WHERE column='members'
When you save a object with saveOrUpdate() the objects id field will get updated with the auto generated id if it was a create operation. So that it will never conflict with id which was already generated and used.
I'm dealing with a legacy database that uses a strange key/ID configuration for one of its tables. It's the table that defines user information. Here are the columns (I've simplified things a little):
ID
Secondary ID
First Name
Last Name
Change Type
All of these columns are part of the key in the database itself and are needed to uniquely identify a row, with one exception. When the Change Type column has a null value then the ID column uniquely identifies a row. This exception is heavily relied on to get a user's name based on their ID. However I need to specify all columns as #Id for hibernate to work correctly with this table ... or do I? Assuming I do, how would I go about also implementing the exception so that objects can be loaded from the database by just the ID? Ideally I'd like to be able to interact with this object as if ID was the only key since in practice that's how it's done in straight SQL by the DBAs.
I have one question that if we are creating any table in database i.e. not having any primary key(all columns values are nullable).
can't we do mapping without ID field in Hibernate O/R Mapping i.e. .hbm.xml file while working with hibernate.
The problem which i am facing is my .hbm.xml file without ID field is not getting validated.
I got the answers from u all, but i have one question that can we use transient keyword prefixed to ID variable in the entity class so that not to persist that value into database?
The only real solution is to fix your broken data model. An entity that does not have a primary key is not relational data, so you can't expect an ORM product to be able to know how to handle it.
And how Hibernate will perform update without a primary key or an uniquely identified row?
Thanks.
You cannot do that in hibernate. And you shouldn't do it anyway. Databases warn you that it is not advisable not to have a primary key.
If you really don't have a set of columns that form a unique key, you have two options:
add an auto-increment primary key (preferred)
use raw JDBC to get the data from that particular table. You can do that with hibernate's session.doWork(..) method.