Spring/Hibernate: двунаправленное отображение без синхронизации только для запросов JPQL

При двунаправленном сопоставлении между объектами (например, @ManyToOne@OneToMany), контрагент должен быть синхронизирован при каждом изменении, особенно при использовании кеша 2- го уровня. Обычно это делается с помощью вспомогательных методов. Эти вспомогательные методы не работают хорошо, если Many часть содержит много записей, потому что весь набор выбирается каждый раз. Простым примером может быть объект Store котором есть n Products, тогда как n очень велико. Для добавления нового Product в Store потребуется, чтобы Store достало весь список Products чтобы, наконец, добавить его в набор (см. Пример кода ниже).

Можно утверждать, что при моделировании такого отношения было бы лучше представлено однонаправленной связью от Product к Store. Однако мы используем много запросов JPQL в нашем приложении. В JPQL очень удобно объединять объекты с обеих сторон.

Вы видите какие-либо проблемы при сопоставлении отношения @OneToMany в объекте Store, когда Many самом деле означают множество, а не только несколько, и просто делают поле частным, без геттеров и сеттеров, при условии, что все отношения лениво взяты? Насколько я понимаю, Hibernate просто нуждается в поле для сопоставления отношения. И если набор является конфиденциальным, не должно возникать проблем с производительностью?


Объект Product:

@Entity
@Table(name = "product")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Product {

  @ManyToOne(fetch = FetchType.LAZY)
  private Store store;

  // setter, getter, helper methods
}

Объект Store:

@Entity
@Table(name = "store")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Store {

  @OneToMany(mappedBy = "products", fetch = FetchType.LAZY)
  @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
  private Set<Product> products;

  // setter, getter, helper methods
}

Ответ 1

Нет, в этом нет ничего плохого, это техника, которую я часто использовал. Разумеется, просто убедитесь, что в каком-то контексте в поле зрения не обращаются рефлексивно (например, автоматические сборщики toString и аналогичные утилиты, которые вы можете использовать).

Кроме того, вам не нужна аннотация @Cache поскольку вы никогда не получите доступ к коллекции в любом случае, поэтому она никогда не будет кэшироваться.