Подтвердить что ты не робот

Если постоянные классы инициализируют коллекции переменных экземпляра

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

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

    ...getters and setters...
}

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

public class Basket {
    private List items;

    ...getters and setters...
}

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

4b9b3361

Ответ 1

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

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

И...

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

Только DTO

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

Соответствующие классы моделей

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

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

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

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