I want to define a bidirectional @OneToMany relation. I did it the following way:
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnore
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private List<CustomerEmployeeRole> roles;
// more fields
}
public class CustomerEmployeeRole {
@ManyToOne
@NotNull
private Customer customer;
// more fields
}
Everything works as expected, the only problem is that n+1 queries are executed when i delete a customer. n is the number of roles the customer has. For every role the following query is executed:
delete from customer_employee_role where id=?
It would be possible to delete all roles in one query:
delete from customer_employee_role where customer_id=?
I assume hibernate does n+1 queries because of mappedBy = "customer"
. I want to keep the annotation, because i want to avoid a join table. Is there any way to tell hibernate to only execute one query instead of n queries in this case? Otherwise i would have to write my own queries which would work too, but it´s not really elegant.
The n+1
queries are because of the CascadeType.ALL
. Since you set this attribute, the CustomerEmployeeRole's are deleted too. So if you want to remove a Customer let's see what happens assuming that the customer have 2 roles:
1) delete from CustomerEmployeeRole where id =..
2) delete from CustomerEmployeeRole where id =..
3) delete from Customer where id =.. here is your +1
query.
PS: In case you have any more questions about which is the best way to map a @OneToMany
, @ManyToMany
, @OneToOne
or what is happening behind the scenes this is a good tutorial. ( Same for the other annotations )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.