Приложение, в котором я работаю, использует 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 или state-changin g dao.
Теперь ошибка, которую я хотел бы предотвратить, это то, что случайно происходит building.getInhabitants().clear();
. Я думаю, что один из этих вариантов:
Getter оберточной: Сделайте
getInhabitants
первую оберткуinhabitants
вCollections.unmodifiableSet()
вызова, а затем вернуть его.- Плюсы: Меньше работы, как минимум дополнительный код
- Минусы: Чувствует Hacky
Wrapper классы: Переименовать
Building
вMutableBuilding
,Person
кMutablePerson
и обеспечивают неизменные классыBuilding
иPerson
. Поскольку мое приложение имеет четкую точку моментального снимка, я могу получить записи как изменяемые объекты (как и сейчас), сделать глубоко неизменные копии и представить это дерево объектов клиентам.- Плюсы: Прямая java, no Hibernate magic. Я использую свое любимое ключевое слово:
final
- Против: больше кода для написания и обслуживания. Кроме того, будет ли Hibernate сохранять изменяемые экземпляры в памяти?
- Плюсы: Прямая java, no Hibernate magic. Я использую свое любимое ключевое слово:
Hibernate отображение магии: Используйте это один магический ключевое слово, чтобы инструктировать Hibernate, чтобы обернуть коллекции он устанавливает на своих объектах сущностей в
Collections.unmodifiableSet()
или эквивалент.(Примечание: Я использую файл сопоставления XML)- Плюсы: Элегантный, без дополнительного кода
- Минусы: Такое ключевое слово может не существовать
расширение Hibernate: Используйте это одно расширение Hibernate укажите, как создать собственный экземпляр объекта, а затем верните его в
Collections.unmodifiableSet()
.- Плюсы: Более элегантно, чем взлом моим Геттеры
- Минусы: Такая точка расширения может не существовать
Сейчас я склоняюсь к # 2, в основном потому, что я не знайте, возможны ли 3 и 4.
Каков наилучший способ?
+1 для напоминания, почему мы пишем геттеры и сеттеры :-) – KarlP
Это действительно лучшее решение. Я просто должен согласиться с тем, что изменяемые классы иногда в порядке! :) – oksayt