简体   繁体   中英

Hibernate - ManyToOne / OneToOne with Cascade options

Say I have a class A , which has an attribute of class B .

I know that there will only ever be one class B for every class A , so I map this with OneToOne . If I mistakenly add the same class B to a second class A , both class A s reference the same class B (and so, with CascadeType.ALL set, a delete on one of these objects will remove the address referenced by the other). This all makes sense.

However, if I know that there may be multiple (same) instances of class B in the database, and I want any class A s to use this persisted attribute if it exists, I thought I could map this entity as ManyToOne and JPA / hibernate would take care of any necessary checks to see if the data is already in the database (loading and then using equality). It seems this isn't the case.

The ManyToOne relationship works in exactly the same way as the OneToOne above - ie as soon as I delete one of the class A objects that references a class B object, the 'class B' object gets deleted, too (even if referenced elsewhere). I would expect JPA / hibernate to check this class B object isn't referenced by any other class A object before deleting (even with CascadeType.ALL set - as it is marked up as a ManyToOne relationship).

Am I missing something here?

Unfortunately, there is no simple way to get what you want.

A cascading remove is very simple: if the entity on the cascading side is removed, the entity on the referenced side is also removed. Even if it is referenced by other entities. Well, hopefully, foreign key constraints in the database will prevent the underlying row being deleted, and an exception will be thrown, but the point is that the JPA provider will attempt to remove the entity. It sounds like this is not the behaviour you want, so cascading removal is not for you.

JPA also has a feature called orphan removal, but this has a similar limitation - it can't be used to manage shared objects. You can't even declare it on a @ManyToOne relationship.

Rather, i think you will need to handle this deletion manually. Instead of deleting the owning objects directly using the EntityManager , encapsulate the deletion in a service object (sometimes called a data access object or a repository) that deletes the object, and then checks to see if its referenced object should also be deleted.

I appreciate that this is awkward. But sadly, as far as i know, this is not something that JPA can automate for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM