jherranzm
jherranzm

Reputation: 155

Spring JPA: When I delete an entity, the entities related are deleted too

First of all, thanks for be interested in this question.

The scenario is like that: there is an entity Usuario (user) which has several Role. When I delete an User, all Roles related are deleted too.

The code for Role is:

@Entity
@Table(name = "marte_role")
@XmlRootElement
public class Role implements Serializable {

private static final long serialVersionUID = 1L;

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

private String nombre;

@ManyToMany(
        fetch = FetchType.EAGER, 
        targetEntity = Usuario.class, 
        cascade = { CascadeType.ALL })
@JoinTable(
        name = "marte_usuario_role", 
        joinColumns = { @JoinColumn(name = "role_id") }, 
        inverseJoinColumns = { @JoinColumn(name = "usuario_id") })
@JsonIgnore
private List<Usuario> users = new ArrayList<Usuario>();

... Getters/setters/builders...

And the code for Usuario is:

@Entity
@Table(name = "marte_usuario")
@XmlRootElement
public class Usuario implements Serializable {

private static final long serialVersionUID = 1L;

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

private String username;
private String password;
private String email;
private boolean enabled;

@ManyToMany(
        fetch = FetchType.EAGER
        , targetEntity = Role.class
        , cascade = { CascadeType.ALL })
@JoinTable(
        name = "marte_usuario_role"
        , joinColumns = { @JoinColumn(name = "usuario_id") }
        , inverseJoinColumns = { @JoinColumn(name = "role_id") })
private List<Role> roles = new ArrayList<Role>();

@Transient
private int numRoles;

It seems to me that is related with CascadeType.ALL. I've tested with CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, instead of CascadeType.ALL and then the entity is NOT deleted.

Does anyone know what I am doing wrong?

Thanks in advance for your answers.

Upvotes: 2

Views: 2071

Answers (3)

jherranzm
jherranzm

Reputation: 155

Solved!

The answers provided are both correct: remove CascadeType.ALL, but just in the Role entity. With this change is possible to remove an Usuario, without deleting all the Role related.

@Entity
@Table(name = "marte_role")
@XmlRootElement
public class Role implements Serializable {

    private static final long serialVersionUID = 1L;

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

private String nombre;

@ManyToMany(
        fetch = FetchType.EAGER, 
        targetEntity = Usuario.class
        )
@JoinTable(
        name = "marte_usuario_role", 
        joinColumns = { @JoinColumn(name = "role_id") }, 
        inverseJoinColumns = { @JoinColumn(name = "usuario_id") })
@JsonIgnore
private List<Usuario> users = new ArrayList<Usuario>();
...

Thanks!

Upvotes: 1

gipinani
gipinani

Reputation: 14398

CascadeType.ALL include also CascadeType.REMOVE, that's why your entities are removed with this annotation.

Upvotes: 3

Kayaman
Kayaman

Reputation: 73558

You're not doing anything wrong. You specify CascadeType.ALL, which means all operations, including delete, are cascaded to related entities. If you don't want that to happen, don't use CascadeType.ALL.

Upvotes: 2

Related Questions