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
поскольку вы никогда не получите доступ к коллекции в любом случае, поэтому она никогда не будет кэшироваться.