简体   繁体   中英

CascadeType.ALL without CascadeType.REMOVE changes persist behavior

In this project I have two Entities A and B that each have a OneToOne relationship to Entity C. There are some C that are referenced by A and B.

@Entity
public class A {
    @NotNull
    @OneToOne(cascade = { CascadeType.ALL })
    @JoinColumn(name = "fk_c", foreignKey = @ForeignKey(name = "fk_a_2_c"))
    private C c;
}

@Entity
public class B {
    @NotNull
    @OneToOne(cascade = { CascadeType.ALL })
    @JoinColumn(name = "fk_c", foreignKey = @ForeignKey(name = "fk_b_2_c"))
    private C c;
}

@Entity
public class C {
    @Nullable
    @OneToOne(mappedBy = "c", fetch = FetchType.LAZY)
    private A a;

    @Nullable
    @OneToOne(mappedBy = "c", fetch = FetchType.LAZY)
    private B b;
}

Until now everything was working fine using CascadeType.ALL on field c in Entity B. We now want to delete Entity B without ever deleting Entity C. Thus, we change the cascading in Entity B to

@OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })

Now, the delete behavior is as desired, but when persisting Entity B there is no persist cascading for Entity C, instead we get an org.springframework.dao.InvalidDataAccessApiUsageException

Not-null property references a transient value - transient instance must be saved before current operation : xxx.B.c -> xxx.C

I already tried placing all cascade types (PERSIST, MERGE, REMOVE, REFRESH, DETACH) which, according to the javax.persistence documentation should yield the same result as CascadeType.ALL. The error stated above still occurs.

So: How can I keep the cascading behavior of CascadeType.ALL without REMOVE-cascading?

In an older question/answer Hibernate: CasecadeType.ALL vs {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH, CascadeType.REMOVE} I learned that the CascadeType enum of javax.persistence does not work properly when using hibernates save/saveOrUpdate.

Using session.persist instead of session.saveOrUpdate was not desirable in my case, so I needed to change the cascading on my entity from

@OneToOne(cascade = CascadeType.ALL)

to

@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@OneToOne

Now saving and deleting both work just fine.

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