Приложение, над которым я работаю, использует Hibernate исключительно для извлечения группы постоянных объектов из базы данных в память. Приложение должно время от времени обновлять этот моментальный снимок в памяти из базы данных, и это должно быть единственное соединение с базой данных.
Объекты в памяти затем используются для множества вычислений. Расчеты не должны изменять эти объекты. За исключением того, что где-то случайно прошел какой-то урок, и мне пришлось потратить день на поиски ошибки. Теперь мне интересно, как лучше всего сделать все дерево объектов неизменяемым.
Предположим, иерархия классов выглядит следующим образом:
public class Building { // persistent entity
private String name; // hibernate-mapped property
private Set<Person> inhabitants; // hibernate-mapped collection
// getters
}
public class Person { // persistent entity
private String name; // hibernate-mapped property
// getters
}
Я запретил клиентам доступ к базе данных следующими способами:
mutable = false
в отображениях Hibernate Теперь ошибка I ' Я хочу предотвратить случайное попадание building.getInhabitants (). clear ();
. Я могу придумать следующие варианты:
Обертывание получателя : Сделайте getInhabitants
сначала оберните жителей
в вызове Collections.unmodifiableSet ()
, затем верните это.
Классы-оболочки : Переименовать Здание
в MutableBuilding
, Человек От
до MutablePerson
и предоставляют неизменяемые классы Building
и Person
. Поскольку мое приложение имеет четкую точку снимка, я могу получать записи как изменяемые объекты (как я это делаю сейчас), делать глубоко неизменяемые копии и представлять это дерево объектов клиентам.
final
Магия отображения Hibernate : используйте это одно волшебное ключевое слово, чтобы дать Hibernate команду обертывать коллекции, которые он устанавливает для моих объектов сущностей в Collections.unmodifiableSet ()
или эквивалент. (Примечание: я использую файл сопоставления xml)
Расширение Hibernate : Используйте эту точку расширения Hibernate для записи моего собственного объекта Collections.unmodifiableSet ()
, прежде чем возвращать его.
Верно теперь я склоняюсь к пункту 2, в основном потому, что не знаю, возможны ли 3 и 4.
Каков наилучший способ?