@ManyToOne JPA association and cascade… not sure w

2020-03-18 06:53发布

I'm still not very clear about the way cascade works in deletion operations. I was wondering what happens if I have this:

class myBean{

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        public Cliente getClienteDiAppartenenza() {
            return clienteDiAppartenenza;
        }

}


class Cliente{
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    public List<myBean> getMyBeans() {
        return myBeans;
    }
}

if I delete the myBean with this property I'm not sure if the linked Cliente will be deleted too (weird in a manytoone) or the collection inside Cliente will be updated and that instance of myBean removed, then saved.

What will happen?? Hibernato docs aren't very clear about this...

2条回答
我想做一个坏孩纸
2楼-- · 2020-03-18 07:31

This is not a Hibernate thing, this is part of the JPA 2.0 standard. You have two aspects in your annotations, one thing is the use of orphanRemoval.

You use orphanRemoval when the parent entity has control over the creation and destruction of the child entity. In UML this would be a case of composition that is a strong ownership and concident lifetime of the parts by the whole. The JPA 2.0 specification in section 2.9: Entity Relationships says:

Associations that are specified as OneToOne or OneToMany support use of the orphanRemoval option. The following behaviors apply when orphanRemoval is in effect:

  1. If an entity that is the target of the relationship is removed from the relationship (by setting the relationship to null or removing the entity from the relationship collection), the remove operation will be applied to the entity being orphaned. The remove operation is applied at the time of the flush operation. The orphanRemoval functionality is intended for entities that are privately "owned" by their parent entity. Portable applications must otherwise not depend upon a specific order of removal, and must not reassign an entity that has been orphaned to another relationship or otherwise attempt to persist it. If the entity being orphaned is a detached, new, or removed entity, the semantics of orphanRemoval do not apply.

  2. If the remove operation is applied to a managed source entity, the remove operation will be cascaded to the relationship target in accordance with the rules of section 3.2.3, (and hence it is not necessary to specify cascade=REMOVE for the relationship)[20].

A second aspect would be the use of cascase=REMOVE when no orphanRemoval is implied.

The section 3.2.3: Removal contains details about the remove process:

The semantics of the remove operation, applied to an entity X are as follows:

• If X is a new entity, it is ignored by the remove operation. However, the remove operation is cascaded to entities referenced by X, if the relationship from X to these other entities is annotated with the cascade=REMOVE or cascade=ALL annotation element value.

• If X is a managed entity, the remove operation causes it to become removed. The remove operation is cascaded to entities referenced by X, if the relationships from X to these other entities is annotated with the cascade=REMOVE or cascade=ALL annotation element value.

• If X is a detached entity, an IllegalArgumentException will be thrown by the remove operation (or the transaction commit will fail).

• If X is a removed entity, it is ignored by the remove operation.

A removed entity X will be removed from the database at or before transaction commit or as a result of the flush operation. After an entity has been removed, its state (except for generated state) will be that of the entity at the point at which the remove operation was called.

查看更多
时光不老,我们不散
3楼-- · 2020-03-18 07:44

Your JPA provider isn't going to manage your java collections in memory for you. If you have a relationship mapped in both sides, then one side should be defined as the owning side using the mappedBy attribute in the mapping of the non-owning side. It's up to you to decide which side is the owning side. Once you've made that decision, the JPA provider will keep things up to date in the database using whatever cascade/orphan management you've defined in the mapping but you are left to manage your collections in the non-owning side.

One way to manage this is to have a service method that is used to make the change and that service method takes care of updating the collection or the reference in your 1-n and n-1 side of things so your java objects are correct in memory.

查看更多
登录 后发表回答