How to make Hibernate automatically delete orphaned entity association records

Good morning
I have this case


and these entity models

@Table(name = "PROPOSTA")
public class Proposta implements Serializable{

	private static final long serialVersionUID = -705828064150128352L;

	public Proposta() {
	@Column(name = "COD_PROPOSTA")
	private Integer codProposta;	
	@ManyToMany(fetch = FetchType.LAZY)
	@Cascade({ CascadeType.ALL })
            joinColumns =  @JoinColumn(name = "COD_PROPOSTA"),
            inverseJoinColumns = @JoinColumn( name ="COD_INTESTATARIO")
	private Set<Intestatario> listaProposteIntestatario;

With Intestatario defined in this way

@Table(name = "INTESTATARIO")
public class Intestatario {

    public Intestatario() {

    @Column(name = "COD_INTESTATARIO")
    private Integer codIntestatario;

        ... getter and setter ... 

Everything works properly except in the case of the REMOVE.
When I remove an Entity on “Proposta” Object, the Hibernate framework removes correctly the entries in tables PROPOSTA, PROPOSTA_INTESTATARIO, but remove record in the table INTESTATARIO even if this record are linked to other records in the table PROPOSTA.
I know that this is a common problem linked to the @ManyToMany association.
What is the best way to avoid thi side effect of the @ManyToMany association?
Is this a configuration problem or a framework problem?

You defined that Hibernate should use CascadeType.ALL which means that also REMOVE will cascade. If you don’t want that, you should list out the cascade types that you want.

Thanks Beikov for your answer.
I would like to know if there is some Hibernate configuration that removes the INTESTATARIO record only if there is no other records in the intermediate table (PROPOSTA_INTESTATARIO) linked to it.

I think you are asking for @ManyToMany(orphanremoval = "true") which does not exist in the JPA spec. I think it was to difficult for them to check if the “orphan” can be removed, because of the ManyToX in can be in other entities. For the cases of OneToX it is very easy because it can’t be referenced somewhere else.

Edit: Maybe someone here knows the most efficient way to clean up programmatically? By also changing all Entities in the current session. From the book “Pro JPA 2”:

Only relationships with single cardinality on the source side can enable orphan removal, which is why the orphanRemoval option is defined on the @OneToOne and @OneToMany relationship annotations, but on neither of the @ManyToOne or @ManyToMany annotations.

It’s a bummer, but there is no JPA automated orphan removal for ManyToMany.

There is a way. You just execute a DML query like this DELETE FROM Intestatario i WHERE i.propostas IS EMPTY which will delete all Intestatario that have no propostas assigned. This assumes you have the inverse mapping as well though. You can write the query the other way as well by using a subquery, but I don’t know your exact model.

Thanks for your exaustive response.