ORA-02292: integrity constraint (xxx) violated - child record found - java

How do i delete all the entries using hibernate deleteAll() ?
I have a class with multiple #oneToMany relationships (having like +5000 child entities) and when i try to do deleteAll i get the title error
oracle.jdbc.OracleDatabaseException: ORA-02292: integrity constraint (xxx) violated - child record found
I've tried adding
cascade = {CascadeType.ALL}
and
orphanRemoval=true
to #OneToMany relationship class, but no help.
It's a bidirectional relationship with following classes
#OneToMany(targetEntity = XXX.class, fetch = FetchType.LAZY, cascade = {CascadeType.ALL}, orphanRemoval=true, mappedBy = "zzz")
#Fetch(FetchMode.SELECT)
#JsonManagedReference
private List<XXX> xxx;
#LazyCollection(LazyCollectionOption.FALSE)
#OneToMany(targetEntity = YYY.class, fetch = FetchType.LAZY, orphanRemoval=true, cascade = {CascadeType.ALL}, mappedBy = "zzz")
#Fetch(FetchMode.SELECT)
#JsonManagedReference
private List<YYY> yyy;
with child elements like
#ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
#JoinColumn(name = "XXX", nullable=false)
#JsonBackReference
private XXX zzz;
i also tried HQL DELETE query but that dosent get me anywhere either.
How on earth do i delete all these entities consistently?
So far i've manually droped the tables since this problem started (all entities were deleted fine just few days ago) but thats starting to really annoy me, but i cant figure how to do this.
Thanks!

You have set CascadeType.ALL on your parent and the best way to delete should be call one single delete on parent entity
If you try to delete a child, it can be hibernate will propagate delete on a parent that has still children not still deleted.
Last resort with this king of problem is:
Enable logs on Spring Boot Application
Run sql query generated in SQL server
Find where the error happens evaluating the current database condition
Change JPA if necessary

Related

What happens in `#ManyToOne(cascade = CascadeType.ALL)` and how does it relate to SQL?

I am using Hibernate as an ORM framework.
I have a bidirectional relationship that is implemented in Java as:
#Entity
#Table(name = "Parent")
class Parent {
...
#OneToMany(cascade = CascadeType.ALL, mappedBy="parent", orphanRemoval=true)
private List<Child> child;
}
#Entity
#Table(name = "Child")
class Child {
...
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "parent_id")
private Parent parent;
}
Further the relational database table "Child" does have the following foreign key specification
fk_child_parent FOREIGN_KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
Question 1: Is it bad practice that the child class's foreign key is annotated with cascade = CascadeType.All? Based on my current understanding, I would assume that whenever I delete a child, I cascade the transaction and delete the parent as well.
Since the parent might have more than one child, this will leave some orphan childs which will be removed due to the orphanRemoval=true option. Is this correct?
Question 2: In Java I already specify the cascade operation from the parent down to the children with #OneToMany(cascade = CascadeType.ALL, ...). Is the SQL line, or at least the ON DELETE CASCADE part of it, superfluous?
Vice versa, if I have the SQL line ... ON DELETE CASCADE that specifies the foreign key, can I skip the #JoinColumn or #ManytoOne annotations?
Please excuse if this is trivial question. I am new to databases / ORM, trying to wrap my head around the concepts.
Using CascadeType.ALL is like using all of the CascadeType values i.e. CascadeType.PERSIST, CascadeType.MERGE etc.
Every CascadeType refers to an operation on the EntityManager. If you do entityManager.persist(parent) then Hibernate will automatically do entityManager.persist(child) for every element in the list if you CascadeType.PERSIST is enabled. Same goes for other cascade types.

How to avoid Hibernate to create foreign key restrictions on oneToMany relationship

I have these two entities: Hotel, HotelPhoto
And the following relationship:
Hotel
#OneToMany(fetch = FetchType.EAGER, mappedBy="idHotel")
#OnDelete(action = OnDeleteAction.CASCADE)
public Set<HotelPhoto> getHotelPhotos() {
return hotelPhotos;
}
When I run this code the hibernate is creating a foreign key restriction with RESTRICT on delete and on update. I would like to have a CASCADE restriction on delete and on update. Is there a way to do that and avoid automatically creating a RESTRICT restriction?

Hibernate: Make a ManyToOne relationship work with unmatched key

I have a many-to-one relationship between two objects: SomeProjectType and Work Orders. In SomeProjectType, I have:
#OneToMany(mappedBy = "project", fetch = FetchType.EAGER)
private Set<WorkOrder> workOrders;
SomeProjectType has a "ProjectKey" as the #id for it.
And in WorkOrder I have:
#ManyToOne
#JoinColumn(name = "WorkOrderProjectKey")
private SomeProjectType project;
The issue I am having is that sometimes in WorkOrder, the "WorkOrderProjectKey" has a project key that doesn't exist in SomeProjectType (I am not sure why, but it is by design).
My question is: Is there a way to have Hibernate still return back rows even if some do not match? I have tried "nullable=true" and "optional=true" but it still won't work.
try to this code because i have same problem then i will change code and work properly.
Primary Key Tables
#OneToMany(mappedBy = "project")
private List<WorkOrder> workOrders;
Foreign Key Table
#ManyToOne
#JoinColumn(name = "WorkOrderProjectKey")
private SomeProjectType project;
I got it to work! Under the #ManyToOne, I put the following and it gets everything.
#NotFound( action = NotFoundAction.IGNORE )
Got this from the answer here:
Hibernate chokes on missing rows when dealing with a legacy database

Make 2 different Parent Entities reference a Child Entity through #OneToMany in JPA

I have a somewhat strange question, I don't know if this is supported in JPA:
I have an #Entity Child and two other entities, #Entity Parent1 and #Entity Parent2.
What I would like to do, is have a #OneToMany relationship between Parent1 and Child, and another #OneToMany relationship between Parent2 and Child.
The reason is that I want Childs to be deleted if their Parent1 is deleted, and Childs to be deleted if their Parent2 is deleted.
I have tried many combinations but I can't get it to work...
TL;DR: Any Child that does not have a Parent1 AND a Parent2 should be deleted.
Here is my code right now (ommitting #Id and getter/setters):
#Entity
class Parent1 {
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
Set<Child> childs;
}
#Entity
class Parent2 {
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
Set<Child> childs;
}
#Entity
class Child {
String name;
}
Thank you,
Yes as per #jmvivo answer you need to use orphanRemoval=true is solution of your use-case ,
Here As per Oracle On this link
When a target entity in one-to-one or one-to-many relationship is removed from the relationship, it is often desirable to cascade the remove operation to the target entity. Such target entities are considered “orphans,” and the orphanRemoval attribute can be used to specify that orphaned entities should be removed. For example, if an order has many line items and one of them is removed from the order, the removed line item is considered an orphan. If orphanRemoval is set to true, the line item entity will be deleted when the line item is removed from the order.
You might also want to look at below SO Question as you go further with your requirement
One to Many relationship JPA/Hibernate removing links
JPA 2.0 orphanRemoval=true VS on delete Cascade
Reading OneToMany.ophanRemoval, you can try this:
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval=true)
Set<Child> childs;
Good luck!
You will have to handle this on service/DAO level, I don't think you'll find any JPA support for this specific use case. Just manually check the conditions prior to deleting the parent/child.

Hibernate refuses to generate tables with OnDelete annotation [duplicate]

I have inherited a code base on which nearly all relations have the following annotations:
#OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, mappedBy = "someThing")
#OnDelete(action = OnDeleteAction.CASCADE)
Now I'm having trouble understanding what #OnDelete does in the first place. Hibernate: OnDelete vs cascade=CascadeType.REMOVE is interesting, but unfortunately doesn't have any answers and the JavaDoc for #OnDelete is particularly worthless.
From the other questions it looks like the OnDelete annotation somehow lets the DB do the cascading, while the cascading directive on #OneToMany let's the ORM do it, but what would ever be the purpose of using them together?
And does #OneToMany's cascade directive really doesn't allow the ORM implementation to generate a DB based cascade anyway?
Let's say you have a one-to-one directional relationship
class House {
#OneToOne
Object door;
}
If you use CascadeType.REMOVE then deleting the house will also delete the door.
#OneToOne(cascade=CascadeType.REMOVE)
Object door;
If you use #OnDelete then deleting the door will also delete the house.
#OneToOne
#OnDelete(action = OnDeleteAction.CASCADE)
Object door;
Read more here: https://rogerkeays.com/jpa-cascadetype-remove-vs-hibernate-ondelete

Categories