How to efficently truncate a many-to-many table in JPA? - java

I have a JPA many to many relation.
The easiest way of deleting all entries of this relation is doing a findAll(), clearing the collection of the assoziation and flushing the session.
In my case this means loading ~1'000'000 instances into ram just to delete them all. That's not really efficient.
I could resort to SQL and simply truncate the join table. Is there an efficient way to do this in JPA?

You would need to map your m-m table as an additional entity and delete it with a delete statement. If the table is not mapped to an entity, it cannot be deleted by a delete statement. If you just want to delete the m-m relations, this should be enough. If you also wnat to delete related entities, you should map them to the new m-m entity and mark the relationship with cascade on delete.

Related

Hibernate NonUniqueObjectException

I'm getting NonUniqueObjectException in hibernate.
There is one Item class, I saved list of Item objects using session.save of hibernate.
Now in the same transaction, I'm trying to update same Items using raw sql query which has join with another table. This gives me NonUniqueObjectException. The two tables I'm joining are unrelated as entities for hibernate, that is, there is no foreign key relation.
So I have 2 questions:
First, is there any way of using hql for writing inner join queries in hibernate.
Second, how to avoid NonUniqueObjectException.
One of the things that is working is that I clear the session before making any raw sql query. Any better approach is welcomed.

Hibernate make joins on save cascade

Let´s say I have an entity A that has a relationship oneToMany with B with cascade ALL type and by default lazy.
My question now is, what happend, if now I modify A, but B keep in session exactly the same, and I save A. Hibernate will do the join with B and he will update on database, or he will keep B as hibernate proxy?.
We´re facing some problems on our application, since MySQL is complaining for the maximum number of joins when we save the top level entity.
ERROR 1116 (HY000): Too many tables; MySQL can only use 61 tablesin a join
Regards.
I had a similar problem, but with eager fetched relationships. Once we changed them to lazy, the problem was gone.
Hibernate shouldn't make joins with other lazy-related tables when updating only table A in your example, but best is to print out the generated SQL and see if and how it changes when you change your fetch settings.

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.

Update all table data at a time in JPA

Is it possible to update all table data in one query?
I have a Database table Person and corresponding Entiry PersonEntity, I can get all Person data vi a JPA in a list such as List personAll.
I have several CRUD operation on personAll instance, I want to reflect all these changes to the Database in one hand using Hibernate JPA
In other words I want content of Person Table is replaced with new content of personAll instance?
Actually long solution way of this question is execute several insert, delete and update operations. But there should be a easy way of doing it?
I can do similar thing when there are two tables Shool Student table if there is OneToMany relation between eash other? Hibernate JPA value removing OneToMany relation
Thanks
It depends on how many rows there are in your table.
If you load all the rows into a Hibernate session and modify the returned instances as required, any changes will be automatically persisted to the database by Hibernate when the session is flushed.
The reason it depends on the size is that if you load the contents of a huge table into a Hibernate session you risk out of memory errors and even if you don't run out of memory the flush will be very slow since every entity in the session much be checked for modifications.

How to delete a ManyToMany item using JPQL?

I have two models, say :
BlogPost(title, message)
Tags(name)
Both have a ManyToMany relationship defined.
Using JPQL, I delete a list of BlogPost with this query:
DELETE FROM BlogPost b WHERE b IN :list
(:list is a List from a previous SELECT requet).
Doing so, I have a ConstraintViolationException because of the relation between BlogPost and Tags.
Is there a way to delete the relation without deleting the Tags using JPQL?
Thanks for your help!
You have to remove the association first, before you delete the entity.
JPA create a table BlogPost_Tags which stores ID of BlogPost and Tags.
So when you try to delete a BlogPost, the constraint on the BlogPost_Tags failed.
You need to delete the relation before delete the Post, and there is no easy way in JPQL, you have to use the EntityManager.
I'll answer myself with the solution I came up. I'm not sure it's the best one, but at least, it works.
Since you want to bulk delete something that have a ManyToMany related items, you first have to delete the relation (in the join table), or do a loop and for each item, delete manually (insane and too much heavy).
So, since JPQL does not allow to do it, a possible way is to make a native SQL query for deleting the id you want in the related table, and then, do the bulk delete.

Categories