I have a method that creates a #Transactional and fetches some entities A and creates some entities B that have relationship to A.
Inside this method, I need to persist an entity C that has a #ManyToMany relationship to A, however this persistence needs to happen no matter what, so in the save method of C's repository, I add a #Transactional(propagation=Propagation.REQUIRES_NEW).
The problem is when I try to persist C, the A's in the relationship are in another Session.
Is it possible to save C and it's ManyToMany relationship table without attaching A to the session? All the A's in the relationship have have been already persisted hence they have ids, and that is all I need to persist in the auxiliary table.
Related
TL;DR: Is it enough to call repository.save() on the owning entity to persist the relationship or do I need to save both entities?
Let's say I have two entities, A and B and a oneToMany relationship between them. A can have multiple B's, B can have an A. B is the owning side of the relationship (has the foreign key). If I have two, already persisted entities and want to add and persist a relationship between them, then I typically do this:
a.addB(b);
b.setA(a);
bRepository.save(b);
My question is, do I also need to call aRepository.save(a)? Thanks in advance, Googling didn't help me to find the answer.
If as you describe the relationship is owned by B, A didn't change at all as far as JPA is concerned. So it doesn't need to get persisted.
If you have persisted or loaded A and B in the current session, no save at all is technically necessary. JPA keeps track of the entities, note that they are changed and will flush the changes to the database at the end of the transaction.
Good question and assuming that you have already saved the A entity the answer should be that you do NOT need to save the parent A entity again since you have added the child entity B to A's list of children yourself and A is already persisted.
If you ever reload A and all its children you should get the same list as you currently have.
Since it is lazy loaded your query should specifically load the children in the case you want that otherwise you might get into the situation where you assume that A has all its children but you doesn't if you reloaded A from the database without getting them.
In general though I have to question why you are keeping A around in the first place. Caching can be a good thing but your cache should refresh A when its children are updated and should fetch all of A's children if that is what is needed. In that case you don't need to add the new child to A yourself b/c it will be overwritten anyway. Probably doesn't hurt, but why do you want to second guess the cache?
More generally the pattern is simply to save B and be done with it. If your code needs A and all its children it should fetch from the database when needed.
These thoughts do not include JPAs entity cache since I have not attempted to get into very specific detail about that.
So, let's say that I have an object A which has a many to many relationship with object B(B is an entity to a config table in the db which means that the values are not insertable nor updateable.
If I want to save an object A with a list of objects B, is it enough if I provide only the ID of the object B or should I do a query with the ID to get the entire object in order for JPA to do the mapping?
Thanks!
If you are using JPA you need the "complete" objects before persisting them. This means that in your case you will need to get all objects B from the database, then set them in the object A that you are trying to persist and then finally save object A.
My question is would Spring JPA throw exceptions for every query?
I mean, let say there are tables without any relation (FK) between them in database. It is bad design but you cannot change it and it is not up to you.
But you know that data itself should be as there are relations.
That's why you create Entity model with all relations like they are there.
But as I said there is no real relations in database.
And in one point data are inconsistent in database.
Would Spring JPA throw exceptions if there are inconsistency or it will just return you inconsistent data?
I assume with "relations" you mean "foreign keys".
JPA doesn't care about foreign keys.
All it cares about is if the data matches the mapping information on the entities.
So if you have an entity A that references an entity B with id b but such a B does not exist you might eventually get an exception.
Or you might just get an A with a null reference to B.
If the reference is marked as mandatory you might actually not be able to load the A in the first place, because a join is used and therefore not returning any data at all.
Side note: All this depends more on the JPA implementation you are using than on Spring Data JPA.
I have two entities with unidirectional #OneToMany Lazy relationship. When I try to add a child, it seems like Hibernate 4 (my JPA provider) actually performs
Select query
Delete all children with that parent id on join table
Reinsert back all and the new child on join table
How to make Hibernate to just insert the child I wish, without changing my relationship?
By default, a unidirectional #OneToMany relationship will use a join table, it will perform operation as my question. If you are using JPA2 and do not use polymorphic on parent, you may add #JoinColumn, which will create foreign key on children table instead of another join table. JPA provider then will not perform delete and reinsert again.
making relationship bidirectional will solve your problem. you can read some information here
I have two entities which can be related, but they can both exist without having each-other as well. In essence they are both 1 to 0..1.
Entity B can have an Entity A created from it - when this is done it establishes a relationship so that Entity B has 1 Entity A. Like-wise, since it can return to being optional, the user must be able to delete entity A without deleting its parent Entity B.
In the database my Entity A does not have an Entity B foreign key, so deleting Entity B would never be a problem.
Entity B, however, has a nullable field to hold an Entity A foreign Key. So far I've been able only to get Nhibernate to leave the bad key in the table, or delete the associated row entirely when you delete it's associated Entity A.
Long story short, if I click delete on Entity A, it should null out the reference to it in the Entity B table, should one exist. How can I go about this in Fluent Mapping?