SJC
SJC

Reputation: 3007

Deleting Parent setting Child values to NULL not deleting them

I have an User entity which has a list of roles. When I delete the user I expect the children roles to be deleted too. However the foreign key is just set to null and its not deleted. Can you please explain why this behaviour is occurring. I added CascadeType.ALL which I thought would delete the child roles.

User.java

@SerializedName("userrole")
@Expose
@OneToMany(mappedBy = "user", fetch=FetchType.EAGER, cascade = CascadeType.ALL)
private List<Role> userRoles = new ArrayList<Role>();

Role.java

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long     id;

@NotNull
private RoleEnum role;

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user")
private User     user;

Table after delete

+----+------+------+
| id | role | user |
+----+------+------+
|  1 |    0 | NULL |
|  2 |    1 | NULL |
|  3 |    2 | NULL |
|  4 |    3 | NULL |
|  5 |    4 | NULL |
|  6 |    5 | NULL |
|  7 |    6 | NULL |
|  8 |    7 | NULL |
+----+------+------+

Any help would be much appreciated.

Upvotes: 1

Views: 3600

Answers (1)

Bunti
Bunti

Reputation: 1760

You can achieve this with orphanRemoval attribute. Quoting the relevant part from the JPA 2.0 Spec.

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

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.

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

So your OneToMany annotation will look like,

@OneToMany(mappedBy = "user", fetch=FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval=true)

Upvotes: 2

Related Questions