Как я могу загрузить набор с отображением Hibernate как неизменяемый набор?

Приложение, над которым я работаю, использует 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
  • , не предоставляющих никаких экземпляров сеанса Hibernate или методов dao с изменением состояния.

Теперь ошибка I ' Я хочу предотвратить случайное попадание building.getInhabitants (). clear (); . Я могу придумать следующие варианты:

  1. Обертывание получателя : Сделайте getInhabitants сначала оберните жителей в вызове Collections.unmodifiableSet () , затем верните это.

    • Плюсы: Меньше работы, меньше лишнего кода
    • Минусы: Кажется хакерским
  2. Классы-оболочки : Переименовать Здание в MutableBuilding , Человек От до MutablePerson и предоставляют неизменяемые классы Building и Person . Поскольку мое приложение имеет четкую точку снимка, я могу получать записи как изменяемые объекты (как я это делаю сейчас), делать глубоко неизменяемые копии и представлять это дерево объектов клиентам.

    • Плюсы: Прямая java, никакой магии Hibernate. Я использую мое любимое ключевое слово: final
    • Минусы: Больше кода для написания и поддержки. Кроме того, будет ли Hibernate сохранять изменяемые экземпляры в памяти?
  3. Магия отображения Hibernate : используйте это одно волшебное ключевое слово, чтобы дать Hibernate команду обертывать коллекции, которые он устанавливает для моих объектов сущностей в Collections.unmodifiableSet () или эквивалент. (Примечание: я использую файл сопоставления xml)

    • Плюсы: Элегантный, без лишнего кода
    • Минусы: такое ключевое слово может не существовать
  4. Расширение Hibernate : Используйте эту точку расширения Hibernate для записи моего собственного объекта Collections.unmodifiableSet () , прежде чем возвращать его.

    • Плюсы: Более элегантно, чем взлом моих геттеров
    • Минусы: Такая точка расширения может не существовать

Верно теперь я склоняюсь к пункту 2, в основном потому, что не знаю, возможны ли 3 и 4.

Каков наилучший способ?

6
задан oksayt 13 January 2011 в 15:32
поделиться