Updating existing JPA child entities with FK in a single query - java

I have a parent/child one-to-many unidirectional relation.
Both the parent and the child POJOs use custom Insert-on-duplicate-update insert queries specified via #SQLInsert annotation.
Parent/child pair is inserted via cascading - everything works fine and the entity manager is closed.
Then I create a new entity manager and try to insert the same parent/child pair, but with updated values (same primary keys, but some of the other fields are changed).
The parent's Insert-on-duplicate-update works just fine and the values are updated.
In the child table however we end up with 2 entries, one with the old values and NULL parent_id foreign key, and one with the new values and correctly set FK.
I looked at the queries generated by Hibernate and found out the following:
The child row is inserted with the foreign key set to NULL
Then an update query is ran that sets the parent_id for the given child id
Another update is ran that sets the parent_id to NULL, I'm assuming for the child id of the first row
A third update query is ran that sets the parent_id
Is there a way for cascading insert to insert the child row and set the FK in the same query, thus eliminating the need for running a separate update query?

The question was answered as a part of a different question of mine:
JPA insert parent/child results in MySQLIntegrityConstraintViolationException
Basically, you have to set nullable = false in the #JoinColumn that specifies creates the parent/child relation.
There still seems to be an update query running for some reason but the complete record is being inserted with the insert statement.

The accepted answer did not solve my problem.
Adding updatable=false to the parent entity solved it. JPA does not execute the update query. However, I have no clue why that's the case and in fact, I don't think what I am doing is correct because it means I cannot update the child table later on if I have to.

Related

Spring Boot JPA how to handle #Id if I use composite key

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.

Hibernate one to many mapping DataIntegrityViolationException

Hibernate One to many relation Below Process will work
insert into parent table
insert into child table
update the parent primary key in child table
Suppose if i am having a foreign key constrain in database for parent and child table
my step 2 will fail as with DataIntegrityViolationException.
What is the best solution
Heading
You should go with hibernate inheritance feature to achieve this

JDBI how can I delete data from two tables in one #SqlUpdate

I have two tables:
entities:
- id
- someValues
and other table, with foregin key on id field
connectedEntities:
- entityId (foregin)
- otherObjectId (foregin)
I need to delete entity by id, but when I tried to delete just from entities table, there's FK violation.
Also, I want to use #SqlUpdate or other annotation from JDBI framework.
Does anybody know how to do something like this?
Thanks to #G_H , I found what I was looking for.
I just needed to add ON DELETE CASCADE to my foregin key definition, and everything worked just fine.
Here's the tutorial - mysqltutorial.org/mysql-on-delete-cascade

Get the specific column involved in a FK Exception

I faced with the follow message error (DataIntegrityViolationException) in an attempt of delete a specific record in my table:
Cannot delete or update a parent row: a foreign key constraint fails (company.table_parent, CONSTRAINT table_parent_ibfk_1 FOREIGN KEY (id_son) REFERENCES layout (id))
I already know the cause: I'm attempting to delete a record, however, it is being used in other table.
I'd like to know if exist a attribute that contains the table and the column involved in transaction attempt, order to I could treat properly the exception without check the error message content.
I don't know if this call is included in an outer wrapped transaction. as I see it you can:
(A) make the call and parse the error message. You will know the table/col of violation.
(B) query for existence in FK table (either parent or child) for columns suspected of subsequent violation before the update/delete call.
another way of looking at B is that you might be doing this against the parent table and it is a child table that is barking saying you are about to orphan me

How change hibernate association mapping from 'one to many' into 'many to many'?

The relation between the entities must be changed and I'd like to know is it normal to change the association mapping type and whether the data that already exist in db will be transfered normally? I tried to find information about it but didn't found. Or if the mapping will be changed the data that already exists must be transfered manually via sql queries? Thanks
If the association already uses a join table, and the mapping of the many-to-many keeps using the same join table with the same column names, you won't have to do anything except removing the unicity constraint you could have on one of the ci=olumns of the join table.
Otherwise, yes, obviously, you'll have to migrate your schema, using SQL, or any other tool (FlywayDB, Liquibase, etc.).
I could do it simply:
Let A and B be the original tables.
A->B (N-1) was moved to A<-AB->B (N-N).
I had to
- "remove" the foreignkey column from table A,
in favor of records to be inserted into AB
(made of the two foreign keys leading to A and B)
That's all.
Step one: Replace your Many-to-One annotation by your Many-to-Many annotations.
and lauch hibernate in append mode to generate the N-N table
Step two: Insert record in this N-N table given what is found in the remaining foreign-key column of you 1-N relationship.
Step three: Delete this foreign-key column.

Categories