Hibernate, n + 1 запросов, когда я удаляю сущность в отношении @OneToMany - PullRequest
1 голос
/ 22 января 2020

Я хочу определить двунаправленное отношение @OneToMany. Я сделал это следующим образом:

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
}

Все работает как положено, единственная проблема в том, что n + 1 запросы выполняются, когда я удаляю клиента. n - количество ролей, которые имеет клиент. Для каждой роли выполняется следующий запрос:

delete from customer_employee_role where id=?

Можно было бы удалить все роли в одном запросе:

delete from customer_employee_role where customer_id=?

Я предполагаю, что hibernate делает n + 1 запросов из-за mappedBy = "customer". Я хочу сохранить аннотацию, потому что я хочу избежать таблицы соединений. Есть ли способ сказать hibernate, чтобы выполнить только один запрос вместо n запросов в этом случае? В противном случае мне пришлось бы писать свои собственные запросы, которые тоже работали бы, но это не очень элегантно.

1 Ответ

1 голос
/ 22 января 2020

n+1 запросы из-за CascadeType.ALL. Поскольку вы устанавливаете этот атрибут, CustomerEmployeeRole's также удаляются. Поэтому, если вы хотите удалить клиента, давайте посмотрим, что произойдет, если предположить, что у клиента есть две роли:

1) удалить из CustomerEmployeeRole, где id = ..

2) удалить из CustomerEmployeeRole, где id = ..

3) удалить из Customer, где id = .. , вот ваш запрос +1.

PS: В случае, если у вас есть любые другие вопросы о том, какой способ лучше всего сопоставить @OneToMany, @ManyToMany, @OneToOne или что происходит за кулисами , этот является хорошим руководством. (То же самое для других аннотаций)

...