Должны ли постоянные классы инициализировать коллекции переменных экземпляра - PullRequest
12 голосов
/ 21 декабря 2011

В моих классах Hibernate должны быть инициализированы коллекции экземпляров

public class Basket {
    private List items = new ArrayList();

    ...getters and setters...
}

или оставленный неинициализированным

public class Basket {
    private List items;

    ...getters and setters...
}

это имеет какое-то значение для Hibernate? Я наткнулся на эту документацию по Hibernate , где он инициализирует их HashSet, но я часто видел их оставленными неинициализированными.

Ответы [ 4 ]

8 голосов
/ 21 декабря 2011

Выполнение статической инициализации, как в первом блоке кода, избавляет от необходимости проверки на ноль, и если вы знаете, что будете использовать коллекцию в большинстве случаев, это имеет смысл.

Если, с другой стороны, коллекция используется редко, имеет смысл отложить инициализацию до тех пор, пока вам действительно не понадобится ее использовать.

6 голосов
/ 11 января 2012

Из документации persistent collection Hibernate:

Из-за базовой реляционной модели свойства с коллекционными значениями не поддерживают семантику нулевых значений.Hibernate не различает пустую ссылку на коллекцию и пустую коллекцию.

И ...

Когда вы делаете экземпляр постоянным, вызывая persist (), Hibernateфактически заменит HashSet экземпляром собственной реализации Hibernate Set.

Эта семантика "ненулевая коллекция" и "постоянная" по сравнению с "непостоянной" иногда теряется разработчиками.Для простоты использования объектов Hibernate я предпочитаю:

  • всегда инициализировать все Collections с java.util реализациями
  • всегда кодировать Collection интерфейсы

Как обычно для объекта Hibernate Collection s никогда не имеет значение NULL и избегает ошибок, отмеченных в приведенной выше документации при приведении объекта Hibernate Collection к недопустимой реализации.

0 голосов
/ 11 января 2012

Я не могу подтвердить это какой-либо профессиональной документацией, но вот мое мнение по этому вопросу.Я думаю, у вас есть два возможных пути.

Только DTO

Первый 1008 * полагается на то, что Model Model - это простые DTO, используемые толькодля сохранения данных, без выполнения логики.Здесь вы можете оставить поля POJO неинициализированными , так как Hibernate сделает это автоматически, прежде чем вы получите постоянный объект через Session.Я уверен, что вы уже знаете, что Hibernate будет молча оборачивать все коллекции в свои собственные обертки, которые необходимы внутреннему механизму персистентности.

Правильные классы моделей

Второй подход продвигает POJO немного дальше.В этом сценарии вы можете выполнить некоторую логику в методах getters и setters.Это не такой уж редкий сценарий, в конце концов, он вполне приемлем для MVC, и очень часто возникает необходимость добавить к ним некоторый код.Например - регистрация некоторой информации при вызове метода установки, пример ниже:

public void setItems(List<Object> items){
   LOGGER.info("Setting '{}' new items", items.size());
   this.items = items;
}

В этом случае могут возникнуть проблемы, поскольку, насколько я знаю, коллекция не будет инициализирована Hibernate на этом этапе, В этом случае явная инициализация была бы лучше.

Последнее замечание: я не специалист по Hibernate, я также не знаю, изменилось ли что-нибудь в 4.x, но я знаюЯ пережил эту проблему в какой-то момент.

0 голосов
/ 11 января 2012

Вы должны инициализировать его.Даже если Hibernate, где его инициализировать позже, даже если у него не было содержимого (что я не уверен, что это всегда так), вы должны инициализировать его, чтобы быть уверенным, что он всегда когерентно не нулевой.

ВВ приведенном примере вы можете видеть, что у Cat нет явного конструктора без аргументов, поэтому они имеют для инициализации набора при объявлении.Скорее всего, когда вы видите, что он оставлен неинициализированным, был также явный конструктор без аргументов, который инициализировал его позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...