Issue
Tl;dr: How can I exclude a specific OneToOne-relation from delete cascade in Hibernate?
I have the following entities specified in my application:
Foo:
@Entity
@Table(name = "foos")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@SQLDelete(sql = "UPDATE foos SET deleted = true WHERE foo_id = ?;")
public class FooEntity implements Serializable {
@Id
@GeneratedValue(generator = "foo_seq")
@Column(name = "foo_id")
@Access(value = AccessType.PROPERTY)
private Long id;
... snip ..
@OneToOne(cascade = CascadeType.PERSIST, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "bar")
@OnDelete(action = OnDeleteAction.NO_ACTION)
@EqualsAndHashCode.Exclude
@ToString.Exclude
private BarEntity bar;
}
Bar:
@Entity
@Table(name = "bars")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class BarEntity implements Serializable {
@Id
@GeneratedValue(generator = "bar_seq")
@Column(name = "bar_id")
private Long id;
...
}
The problem I have is that hibernate now that when I delete FooEntity, hibernate cascades delete to BarEntity and runs into a constraint-violation, as BarEntity is still referenced from FooEntitity and therefore cannot be deleted.
Delete I am running is:
repository.deleteById(id);
Hibernate query log:
Hibernate:
UPDATE
foos
SET
deleted = true
WHERE
foo_id = ?;
Hibernate:
/* delete x.x.BarEntity */ delete
from
bar
where
bar_id=?
I know I could null reference to Bar in Foo, but I do want to preserve both objects (and their relation) after soft deletion. I there any way I can achieve this and prevent hibernate from cascading the delete to this particular entity?
Solution
Did you try to change orphanRemoval=true
to orphanRemoval=false
in the OneToOne Annotation?
Answered By - Slevin