[英]Hibernate, n+1 queries when i delete an entity in a @OneToMany relation
I want to define a bidirectional @OneToMany relation.我想定义一个双向@OneToMany 关系。 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+1 个查询。 n is the number of roles the customer has. n 是客户拥有的角色数。 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"
.我假设 hibernate 由于mappedBy = "customer"
而执行 n+1 个查询。 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?在这种情况下,有什么方法可以告诉 hibernate 只执行一个查询而不是 n 个查询? 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
. n+1
查询是因为CascadeType.ALL
。 Since you set this attribute, the CustomerEmployeeRole's are deleted too.因为您设置了这个属性,所以 CustomerEmployeeRole 也被删除了。 So if you want to remove a Customer let's see what happens assuming that the customer have 2 roles:因此,如果您想删除客户,让我们看看假设客户有 2 个角色会发生什么:
1) delete from CustomerEmployeeRole where id =.. 1) 从 CustomerEmployeeRole 中删除 id =..
2) delete from CustomerEmployeeRole where id =.. 2) 从 CustomerEmployeeRole 中删除 id =..
3) delete from Customer where id =.. here is your +1
query. 3) 从客户中删除 id =..这是您的+1
查询。
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. PS:如果您对映射@OneToMany
、 @ManyToMany
、 @OneToOne
的最佳方式或幕后发生的事情有任何疑问, 这是一个很好的教程。 ( Same for the other annotations ) (其他注解也一样)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.