ScArcher2
ScArcher2

Reputation: 87257

JPA Many to Many cascade problem

If I create a Customer and Controller, then associate my Controller with a customer it saves fine.

If I then remove my controller it doesn't remove the relationship between them. This causes an EntityNotFoundException when I load the Customer.

javax.persistence.EntityNotFoundException: Unable to find Controller with id 22

I'd like to know how to map this so that when a Controller is deleted the relationship is also deleted.

Database Tables

The Controller's id is not getting removed from the customer_controllers mapping table.

@Entity
public class Customer implements Serializable{

    private Integer id;
    private Set<Controller> controllers;

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    @ManyToMany(cascade={CascadeType.ALL})
    public Set<Controller> getControllers()
    {
            return controllers;
    }
    public void setControllers(Set<Controller> controllers)
    {
            this.controllers = controllers;
    }
}

@Entity
public class Controller implements Serializable{

    private Integer id;
    private String name;
    private String abbreviation;

    @Id
    @GeneratedValue
    public Integer getId()
    {
            return id;
    }
    public void setId(Integer id)
    {
             this.id = id;
    }
    public String getName()
    {
             return name;
    }
    public void setName(String name)
    {
             this.name = name;
    }
    public String getAbbreviation()
    {
             return abbreviation;
    }
    public void setAbbreviation(String abbreviation)
    {
         this.abbreviation = abbreviation;
    }
}

Upvotes: 1

Views: 15874

Answers (3)

omax
omax

Reputation: 539

Have you checked the javadoc for @ManyToMany? It includes the above example mappings.

Upvotes: 1

Pere Villega
Pere Villega

Reputation: 16439

If you have a ManyToMany then you should map Controller to Customer with a

 @ManyToMany(mappedBy="controllers")

or the other way around, depending on which side is the owning side.

As you have it now the relation is not fully defined and it will fail on events like "Cascade".

Upvotes: 3

mR_fr0g
mR_fr0g

Reputation: 8722

you need to make the relationship bidirectional, so that the controller object is aware of its relationship to the customer. Yhis means that when the controller is deleted the record in the join table is also deleted.

This isn't the exact mapping but it gives you the idea.

@Entity
public class Controller implements Serializable{

    private Integer id;
    private String name;
    private String abbreviation;


    private Set<Customer> customers;


    @Id
    @GeneratedValue
    public Integer getId()
    {
            return id;
    }
    public void setId(Integer id)
    {
             this.id = id;
    }
    public String getName()
    {
             return name;
    }
    public void setName(String name)
    {
             this.name = name;
    }
    public String getAbbreviation()
    {
             return abbreviation;
    }
    public void setAbbreviation(String abbreviation)
    {
         this.abbreviation = abbreviation;
    }
    @ManyToMany(cascade={CascadeType.ALL})
    public Set<Customer> getCustomers()
    {
        return customers;
    }
    public void setCustomers(Set<Customers> customers)
    {
        this.customers= customers;
    }

}

Upvotes: 0

Related Questions